Microsoft .NET Kick Start Chapter 3: Programming with .NET
Feb 19, 2004
59 min read
.NET1.0
C++/CLI
C#
VB
Windows
.NET
Visual-Studio
Dev
Intermediate
virtualization
virtual-machine

by Sams Publishing
Contributor
![]() |
|
Programming with .NET
In This Chapter
- Introduction
- C#
- Visual Basic .NET
- Visual J#
- Managed C++
- Other .NET Programming Languages
- Interoperating with Different Programming Languages
Introduction
Microsoft developers working with Visual Studio and COM/OLE technologies have always enjoyed the benefits of a choice of programming languages for development of applications and components. Well, sort of. (For instance, components developed in one programming language couldn't be "inherited" from another programming language.) With the introduction of the CLR and the .NET Framework, this flexibility in the choice of any supported programming language for .NET components and applications still remains a key requirement. Out of the box, the .NET Framework and the key tool supporting the development, Visual Studio .NET, support four programming languages: Visual C#, Visual Basic .NET, Managed C++ (also known as Visual C++ .NET), and Visual J#. In addition, because CLR has already been recognized as a developing standard, third-party Independent Software Vendors (ISVs) and researchers can "port" other programming languages to compile to the .NET runtime.
The genesis to this programming flexibility occurred for two reasons: flexibility and, ease of migration and skills reuse. For instance, millions of Visual Basic developers worldwide can choose the Visual Basic .NET programming language for utilizing and enhancing their existing skills; C++ and Java developers have the option of using either Managed C++, Visual J#, or the new, innovative C# programming language. All four programming languages have similar common features; most can be used for achieving similar results. Each, however, has its own benefits and differentiators, but most of the differences lie in the language syntax.
This chapter briefly discusses four programming languages. A full description of all the features of each of the individual programming languages deserves a book by itself; there are, in fact, multiple sets of books that discuss each language individually. The rest of this chapter follows a hands-on, down-to-the-code style of introduction to programming languages. Each of the language sections is divided into similar sections:
- Hello World
- Comments
- Data types
- Enumerations
- Arrays
- Variables and constants
- Expressions
- Statements
- Classes
- Inheritance
- Interfaces
- Exception handling
- Events
- Delegates
You'll use sample programs for a hands-on understanding of the key capabilities of the various programming languages.
C#
The C# programming language (pronounced "C sharp") was introduced with the .NET Framework. It represents a milestone in the area of programming language development. Even though the genesis of the new C# language is in existing programming languages such as Java and C++, it represents the most innovative, modern, and even—in most areas—the preferred .NET programming language. C# was introduced to combine the key values of Visual Basic and C++. Whereas Visual Basic had ease of use and high developer productivity, C++ represented the ultimate flexibility and control. C# merges the two; it is relatively simpler than C++ (no pointers, templates, and so on), and it has all the nice object-oriented features of C++ and the ease of use of Visual Basic. No more specific memory allocation is required, as everything is "garbage collected" by the common runtime. In various ways, C# is also similar to the Java programming language, which has gained wide developer support as well. However, whereas Java is intended to be a platform-neutral programming language compiling into byte code and then executed on a virtual machine, C# programs are compiled (like all .NET programming languages) into MSIL (Microsoft Intermediate Language) and, like all applications, are ultimately converted into machine code before execution.
C# Programming Language: The Standard - A key aspect of the .NET platform is that it is based on top of existing and new standards. For instance, the C# programming language has been approved as an ISO standard (23270). More details about the standardization initiative and the standard itself are available at http://msdn.microsoft.com/net/ecma/.
C# follows a code-focused model, targeted for developers who like the simplicity of a modern programming language but typically prefer to write programs by hand instead of generating them with wizards. This enables easier reuse because the code is relatively easier to understand by other developers using it. Key highlights of the C# programming language are the following:
- Ease of Visual Basic with the power of most C++ features
- Similar programming language syntax for C++ and Java developers
- Support for all CLR data types
- Pass by reference and value for parameters
- Operator overloading (not found in Java)
- Capability to run clearly marked "unsafe" code
- XML-based documentation, using special comments
- Integration with Visual Studio .NET for rapid development
Hello World
In this section, you'll take a look at a Hello World C# program. Each C# application is composed of a class. If it is an executable application, one of the classes available should have a static Main()
method that serves as the entry point. (The compiler would warn if Main
was not declared or improperly declared.) The Main
method is overloaded and can have a String
array passed to it as well for any command-line parameters.
using System; namespace hks { public class HelloWorld { public static void Main() { Console.WriteLine("Hello World in C#"); } } }
C# classes are stored in .cs files. After you have saved the preceding program in a file, let's say Hello World, you can compile the program into a .NET executable. You will need to include the .NET Framework SDK's bin folder in your PATH variable. If you have installed Visual Studio .NET, you have a shortcut under Visual Studio .NET Tools called Visual Studio .NET 2003 Command Prompt. This shortcut initializes all the environment variables and provides access to the command-line compilers as well.
csc HelloWorld.cs
Now enter HelloWorld.exe to run the application, and you should see "Hello World in C#" echoed on the screen.
Comments
C# provides a couple of ways to introduce comments in a program; the two most popular are the traditional single-line comments (//
) and the multiline comments (/* */
). In addition, C# provides XML-based comments that can be used to create XML documentation from a set of code files. These XML files can then be processed with an XSLT (XML Stylesheet Language) to convert into online HTML documentation, and so on.
using System; namespace hks { /// <summary> /// A Simple Class /// </summary> public class Comments { public static void Main() { // A Simple comment /* A multi line comment */ Console.WriteLine("Hello World in C#"); } } }
Data Types
Table 3.1 describes how the C# types are mapped into the corresponding .NET Framework types. In a true sense, the C# keywords are really a compact representation for the .NET type.
Table 3.1 C# Data Types
C# Type | Corresponding .NET Framework Type |
Bool | System.Boolean |
byte , sbyte | System.Byte , System.SByte |
Char | System.Char |
decimal , double , single | System.Decimal , System.Double , System.Single |
short , ushort , int , uint , long , ulong | System.Int16 , System.UInt16 , System.Int32 , System.UInt32 , System.Int64 , System.UInt64 |
Object | System.Object |
String | System.String |
Enumerations
C# provides the enumerations programming construct, which provides a human-readable form of a series of related constant values.
using System; namespace hks { public class UseEnumerations { enum CreditCard { Visa = 0, MasterCard = 1, AmericanExpress = 2, Discover = 3 } public static void Main() { CreditCard mycard = CreditCard.Discover; Console.WriteLine(mycard); Console.WriteLine((int) mycard); } } }
Arrays
Arrays provide developers with a structure for storing a collection of values. Apart from arrays, the .NET Framework provides a series of Collections constructs, including Hash Tables and ArrayList
, which provide capabilities such as dynamic sizing. You will look at some of those constructs in the next chapter. Arrays can be processed by a foreach
construct.
using System; namespace hks { public class UseArrays { public static void Main() { String[] days_of_week = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; foreach (string day in days_of_week) { Console.WriteLine(day); } } } }
Variables and Constants
Simple value types can be assigned using the variable =
value construct, whereas reference types are required to use the new
keyword for creating a new instance.
using System; namespace hks { public class UseVariables { public static void Main() { const string HELLO_WORLD = "Hello World"; string message = HELLO_WORLD+ " in C#"; MyClass mc = new MyClass(message); mc.Print(); } } public class MyClass { private String message; public MyClass(String message) { this.message = message; } public void Print() { Console.WriteLine(message); } } }
Expressions
Expressions in C# are very similar to those provided by Java and C++ programming languages.
using System; namespace hks { public class UseExpressions { public static void Main() { int a = 10; int b = 10; int result = a * b; bool check = (a == b); Console.WriteLine(result); Console.WriteLine(check); } } }
Statements
As expected, the C# programming language includes several procedural programming constructs, including if
-else
, for
loop, while
loop, switch
statements, and so on.
using System; namespace hks { public class UseStatements { public static void Main() { string[] message = {"Hello", "World", "in", "C#"}; foreach (string msg in message) { Console.Write(msg+" "); } Console.WriteLine(""); int a = 10; int b = 20; if (a < b) { Console.WriteLine("a<b"); } else { Console.WriteLine("a>=b"); } } } }
Structures
Structures are simply an aggregation of value types and are allocated on the stack and not on the heap. Structures are useful for passing a logical and related set of data values. Structures don't support inheritance but can implement interfaces. For instance, the following program would print Hitesh.Seth followed by John.Doe and illustrates that structures are not reference types.
using System; namespace hks { public class UseStructures { public static void Main() { Person hs = new Person("Hitesh","Seth"); Person jd = hs; jd.FirstName = "John"; jd.LastName = "Doe"; Console.WriteLine(hs.FirstName+"."+hs.LastName); Console.WriteLine(jd.FirstName+"."+jd.LastName); } } public struct Person { public string FirstName, LastName; public Person(string FirstName, string LastName) { this.FirstName = FirstName; this.LastName = LastName; } } }
Classes
Classes, on the other hand, are reference types and hence are allocated on the heap. Classes provide object-oriented constructs such as encapsulation, polymorphism, and inheritance. For instance, the following program would print John.Doe twice, illustrating that objects are reference types, allocated on the heap.
using System; namespace hks { public class UseClasses { public static void Main() { Person hs = new Person("Hitesh","Seth"); Person jd = hs; jd.FirstName = "John"; jd.LastName = "Doe"; Console.WriteLine(hs.GetFullName()); Console.WriteLine(jd.GetFullName()); } } public class Person { private string sFirstName, sLastName; public Person(string FirstName, string LastName) { this.sFirstName = FirstName; this.sLastName = LastName; } public string FirstName { get { return sFirstName; } set { sFirstName = value; } } public string LastName { get { return sLastName; } set { sLastName = value; } } public String GetFullName() { return this.FirstName + "."+ this.LastName; } } }
Inheritance
Classes provide inheritance capability, which allows the derived class to inherit the functionality of a base class and potentially override some of the methods. A class definition consists of constructors and destructors, members, methods, properties, and events. (You will learn more about events later in this section.) Unlike the Java programming language, in C# all methods that are overridden must be marked as virtual
in the base class. The is
operator provides runtime validation if an object is of a particular type. For instance, the following program will return that a FullPerson
object is always a Person
.
using System; namespace hks { public class UseInheritance { public static void Main() { FullPerson hs = new FullPerson("Hitesh","K","Seth"); Console.WriteLine(hs.GetFullName()); Object oHs = hs; if (oHs is Person) { Console.WriteLine("I am still a Person"); } } } public class Person { public string FirstName, LastName; public Person(string FirstName, string LastName) { this.FirstName = FirstName; this.LastName = LastName; } public virtual string GetFullName() { return this.FirstName + "." + this.LastName; } } public class FullPerson : Person { public string MiddleInitial; public FullPerson(string FirstName, string MiddleInitial, string LastName) : base(FirstName,LastName) { this.MiddleInitial = MiddleInitial; } public override string GetFullName() { return this.FirstName + "." + this.MiddleInitial + "." + this.LastName; } } }
Classes can also be marked as either abstract
(Listing 3.1), which means they have to be subclassed for any instances to be created, or sealed
, which does not allow any subclassing.
Listing 3.1 Using Abstract Classes (C#)
using System; namespace hks { public class UseAbstractClasses { public static void Main() { Person hs = new Person("Hitesh","Seth"); Console.WriteLine(hs.GetFullName()); } } abstract public class Abstract { protected string FirstName, LastName; public Abstract(string FirstName, string LastName) { this.FirstName = FirstName; this.LastName = LastName; } abstract public string GetFullName(); } public class Person : Abstract { public Person(string FirstName, string LastName) : base(FirstName, LastName) { } public override string GetFullName() { return FirstName+"."+LastName; } } }
Interfaces
C# provides the concept of interfaces. Interfaces really represent a signature of what needs to be implemented by a derived class. C# supports multiple inheritances of interfaces (Listing 3.2).
Listing 3.2 Using Interfaces (C#)
using System; namespace hks { public class UseInterfaces { public static void Main() { Person hs = new Person(); hs.Name = "Hitesh Seth"; hs.Address = "1 Executive Drive, City, NJ 08520"; Console.WriteLine(hs.GetName()); Console.WriteLine(hs.GetAddress()); } } public interface IName { string GetName(); } public interface IAddress { string GetAddress(); } public class Person : IName, IAddress { private string name, address; public Person() { } public string Name { set { name = value; } } public string Address { set { address = value; } } public string GetName() { return name; } public string GetAddress() { return address; } } }
Exception Handling
C# provides robust exception handling capabilities. For instance, the program that follows catches the exception at runtime and allows messages to be displayed to the end user without requiring an intermediate exit.
using System; namespace hks { public class UseExceptions { public static void Main() { try { int a = 10; int b = 10; int c = a/(a-b); } catch (Exception ex) { Console.WriteLine("Exception Caught"); Console.WriteLine(ex.Message); } } } }
Custom exceptions, which contain more information related to the underlying application, can also be created. Custom exceptions derive from the System.Exception
class. For instance, Listing 3.3 shows the custom exception TooBigDiscountException
being declared and thrown by the constructor.
Listing 3.3 Creating Custom Exceptions (C#)
using System; namespace hks { public class UseCustomExceptions { public static void Main() { try { Discount big_discount = new Discount(56); } catch (TooBigDiscountException ex) { Console.WriteLine("Exception Caught"); Console.WriteLine(ex.Message); } } } public class Discount { private int percent; public Discount(int percent) { this.percent = percent; if (percent > 50) throw new TooBigDiscountException("Discount > 50%"); } } public class TooBigDiscountException : Exception { public TooBigDiscountException(String msg) : base (msg) { } } }
Delegates
Delegates give C# programmers the capability of function pointers, basically passing a function as a parameter. For instance, Listing 3.4 shows two delegates to be created and then invoked.
Listing 3.4 Using Delegates (C#)
using System; namespace hks { public class UseDelegates { public delegate void MyDelegate(string message); public static void Main() { String message = "Hello Delegates"; MyDelegate d1 = new MyDelegate(PrintOnce); MyDelegate d2 = new MyDelegate(PrintTwice); d1(message); d2(message); } public static void PrintOnce(String message) { Console.WriteLine(message); } public static void PrintTwice(String message) { Console.WriteLine("1."+message); Console.WriteLine("2."+message); } } }
Events
A typical use of delegates is in event handling. For instance, take a look at Listing 3.5. It defines a class called Button
, which has a Delegate called EventHandler
. Event handlers can be assigned for the event OnClick
and allow the calling application to pass in the reference of the method Button_Click
as the callback method to invoke after the button is clicked. In this program, the button clicking is done by explicitly invoking the Click
method; in a real GUI application, the Click()
method would be automatically invoked on user input. In Chapter 7, "Developing Windows Applications Using Windows Forms", you will see that the code is very similar to this application.
Listing 3.5 Using Events (C#)
using System; public class Events { public static void Main() { Button button = new Button(); button.OnClick+= new Button.EventHandler(Button_Click); button.Click(); } public static void Button_Click() { Console.WriteLine("Button Clicked"); } } public class Button { public delegate void EventHandler(); public event EventHandler OnClick; public void Click() { OnClick(); } }
That is really all this chapter covers on the C# programming language. Beyond what is covered in this chapter, a major part of this book uses C# as the primary programming language. For further explorations of the C# programming language, see Visual C# .NET 2003 Kick Start by Steve Holzner.
Visual Basic .NET
Visual Basic .NET is the next revision of the popular Visual Basic programming language, which has roots in the BASIC programming language itself. Known for its rapid application development capability, Visual Basic .NET provides developers with the benefits of rapid development with a full-blown object-oriented (OO) programming language. Visual Basic .NET builds on the basic OO features present in Visual Basic and makes the object- orientedness of the language on par with that of Visual C# and even C++.
With its human-readable code syntax, Visual Basic .NET follows a task-oriented model. Focus on increased developer productivity still remains the core mantra for Visual Basic. Key features of the Visual Basic .NET programming language include the following:
- A full, object-oriented, yet intuitive, programming language
- Typical VB features such as implicit typing, late binding, default variable initialization, and optional parameters Enhanced event handling
- Parameterized properties
- -Redeclaration of interface members on implementation
- Command-line/SDK compilers
Hello World
The program listing that follows will look both familiar and different to existing Visual Basic programmers. Familiar is the overall style, subroutines, and modules. What is different in the program is really the additional keyword—Namespace
—and the use of -the .NET Framework class library. An important thing to keep in mind is that Visual Basic .NET is not a case-sensitive programming language.
Imports System Namespace hks Module HelloWorld Public Sub Main() Console.WriteLine("Hello World in VB") End Sub End Module End Namespace
Visual Basic .NET programs are stored with the .vb extension. To compile a Visual Basic .NET program, use the Visual Basic. NET J# command-line compiler, vbc.exe.
vbc HelloWorld.vb
Leverage Your VB Skills with Visual Basic .NET - A key highlight of the Visual Basic .NET programming language is that it allows developers to utilize their existing skills in Visual Basic development. Apart from skills reuse, Visual Basic .NET supports importing existing Visual Basic projects for migration.
Comments
Visual Basic comments are plain old '
style line comments or are identified by Rem
.
Imports System Namespace hks Module Comments Rem Implement the Main Method Public Sub Main() ' Print Out Hello World Console.WriteLine("Hello World in VB") End Sub End Module End Namespace
Data Types
Table 3.2 describes how the Visual Basic .NET types are mapped to their corresponding .NET Framework types.
Table 3.2 Visual Basic .NET Data Types
Visual Basic .NET Type | Corresponding .NET Framework Type |
Boolean | System.Boolean |
Byte | System.Byte |
Char | System.Char |
Decimal , Double , Single | System.Decimal , System.Double , System.Single |
Short , Integer , Long | System.Int16 , System.Int32 , System.Int64 |
Object | System.Object |
String | System.String |
Enumerations
Enumerations are supported in Visual Basic .NET. Listing 3.6 illustrates a potential use.
Listing 3.6 Using Enumerations (Visual Basic .NET)
Imports System Namespace hks Module UseEnumerations Public Enum CreditCard Visa MasterCard AmericanExpress Discover End Enum Public Sub Main() Dim cc as CreditCard cc = CreditCard.Visa Console.WriteLine(cc) End Sub End Module End Namespace
Arrays
Arrays, which are subclasses of the System.Array
type, are supported in Visual Basic .NET (Listing 3.7).
Listing 3.7 Using Arrays (Visual Basic .NET)
Imports System Namespace hks Module UseArrays Public Sub Main() Dim days_of_week() as String = { _ "Sunday", _ "Monday", _ "Tuesday", _ "Wednesday", _ "Thursday", _ "Friday", _ "Saturday" _ } Dim I as Integer For I = 0 to days_of_week.Length-1 Console.WriteLine(days_of_week(I)) Next I End Sub End Module End Namespace
Variables and Constants
Using variables is similar to the traditional Visual Basic programming, using the Dim
keyword (see Listing 3.8).
Listing 3.8 Using Variables and Constants (Visual Basic .NET)
Imports System Namespace hks Module UseVariables Public Sub Main() Const HELLO_WORLD as String = "Hello World" Dim msg as String = HELLO_WORLD & " in VB" Dim mc as New MClass(msg) Call mc.Print End Sub End Module Class MClass private message as String Public Sub New(ByVal message as String) Me.message = message End Sub Public Sub Print() Console.WriteLine(message) End Sub End Class End Namespace
Expressions
Expressions provide the capability to computerize and manipulate data.
Imports System Namespace hks Module UseExpressions Public Sub Main() Dim a as Integer = 10 Dim b as Integer = 10 Dim result as Integer = a * b Dim check as Boolean = (a = b) Console.WriteLine(result) Console.WriteLine(check) End Sub End Module End Namespace
Statements
Statements provide the necessary programming language procedural constructs.
Imports System Namespace hks Module UseStatements Public Sub Main() Dim msg() as String = {"Hello","World","in","Visual Basic.NET"} Dim i as Integer For i = 0 to (msg.Length-1) Console.Write(msg(i)) Next Console.WriteLine("") Dim a as Integer = 10 Dim b as Integer = 20 If (a<b) Then Console.WriteLine("a<b") Else Console.WriteLine("a>=b") End If End Sub End Module End Namespace
Structures
Structures can be used for basic encapsulation of data.
Imports System Namespace hks Module UseStructures Public Sub Main() Dim hs as New Person("Hitesh","Seth") Dim jd as Person = hs jd.FirstName = "John" jd.LastName = "Doe" Console.WriteLine(hs.FirstName & "." & hs.LastName) Console.WriteLine(jd.FirstName & "." & jd.LastName) End Sub End Module Structure Person Public FirstName, LastName as String Public Sub New(ByVal FirstName as String, ByVal LastName as String) Me.FirstName = FirstName Me.LastName = LastName End Sub End Structure End Namespace
Classes
Classes in Visual Basic are defined using the Class
keyword. Like C#, VB classes can have members, constructors and destructors, properties, methods (which are classified into subroutines and functions, depending on whether they return a value), and events (Listing 3.9).
Listing 3.9 Using Classes (Visual Basic .NET)
Imports System Namespace hks Module Useclasses Public Sub Main() Dim hs as New Person("Hitesh","Seth") Dim jd as Person = hs jd.FirstName = "John" jd.LastName = "Doe" Console.WriteLine(hs.FirstName & "." & hs.LastName) Console.WriteLine(jd.FirstName & "." & jd.LastName) End Sub End Module Public Class Person Private sFirstName, sLastName as String Public Property FirstName() as String Get Return sFirstName End Get Set(ByVal Value as String) sFirstName = Value End Set End Property Public Property LastName() as String Get Return sLastName End Get Set(ByVal Value as String) sLastName = Value End Set End Property Public Sub New(ByVal FirstName as String, ByVal LastName as String) Me.FirstName = FirstName Me.LastName = LastName End Sub Public Function GetFullName() as String Return Me.FirstName & "." & Me.LastName End Function End Class End Namespace
Classes can be inherited for overriding and extending functionality present in the base class. The keywords Overridable
and Overrides
are used to set a method in base class as overridable and implementation of the overridden method in the derived class, respectively (Listing 3.10). Similar to C#, Visual Basic .NET also supports only single inheritance.
Listing 3.10 Using Inheritance (Visual Basic .NET)
Imports System Namespace hks Module HelloWorld Public Sub Main() Dim hs as New FullPerson("Hitesh","K","Seth") Console.WriteLine(hs.GetFullName) End Sub End Module Public Class Person Public FirstName, LastName as String Public Sub New(ByVal FirstName as String, ByVal LastName as String) Me.FirstName = FirstName Me.LastName = LastName End Sub Public Overridable Function GetFullName() as String Return Me.FirstName & "." & Me.LastName End Function End Class Public Class FullPerson Inherits Person Public MiddleInitial as String Public Sub New(ByVal FirstName as String, _ ByVal MiddleInitial as String, ByVal LastName as String) MyBase.New(FirstName,LastName) Me.MiddleInitial = MiddleInitial End Sub Public Overrides Function GetFullName() as String Return Me.FirstName & "." & Me.MiddleInitial & "." & Me.LastName End Function End Class End Namespace
Visual Basic .NET supports abstract classes by using the MustInherit
and MustOverride
keywords (Listing 3.11).
Listing 3.11 Using Abstract Classes (Visual Basic .NET)
Imports System Namespace hks Module UseAbstractClasses Public Sub Main() Dim hs as New Person("Hitesh","Seth") Console.WriteLine(hs.FirstName & "." & hs.LastName) End Sub End Module Public MustInherit Class Abstract Public FirstName, LastName as String Public Sub New(ByVal FirstName as String, ByVal LastName as String) Me.FirstName = FirstName Me.LastName = LastName End Sub Public MustOverride Function GetFullName as String End Class Public Class Person Inherits Abstract Public Sub New(ByVal FirstName as String, ByVal LastName as String) MyBase.New(FirstName,LastName) End Sub Public Overrides Function GetFullName as String GetFullName = FirstName & "." & LastName End Function End Class End Namespace
Interfaces
Visual Basic .NET supports interfaces through the Interface
keyword. A derived class can implement multiple interfaces and specifies the specific function/subroutine signature implemented through the Interface
keyword (Listing 3.12).
Listing 3.12 Using Interfaces (Visual Basic .NET)
Imports System Namespace hks Module UseInterfaces Public Sub Main() Dim hs as New Person hs.Name = "Hitesh Seth" hs.Address = "1 Executive Drive, City, NJ 08520" Console.WriteLine(hs.GetName()) Console.WriteLine(hs.GetAddress()) End Sub End Module Public Interface IName Function GetName() as String End Interface Public Interface IAddress Function GetAddress() as String End Interface Public Class Person Implements IName, IAddress Private s_name, s_address as String Public Sub New() End Sub Public WriteOnly Property Name() as String Set s_name = value End Set End Property Public WriteOnly Property Address() as String Set s_address = value End Set End Property Public Function GetName() as String Implements IName.GetName GetName = s_name End Function Public Function GetAddress() as String Implements IAddress.GetAddress GetAddress = s_address End Function End Class End Namespace
Exception Handling
New to Visual Basic .NET is structured exception handling, as illustrated in Listing 3.13. Visual Basic typically had the OnError
/Goto
construct for handling exceptions.
Listing 3.13 Exception Handling (Visual Basic .NET)
Imports System Namespace hks Module UseExceptions Public Sub Main() Try Dim a as Integer = 10 Dim b as Integer = 10 Dim c as Integer c = a/(a-b) Catch ex as Exception Console.WriteLine(ex.Message) End Try End Sub End Module End Namespace Imports System
Similar to C#, apart from handling the extensive set of exceptions defined by the .NET Framework library, custom exceptions can also be defined by subclassing the Exception
class (Listing 3.14).
Listing 3.14 Creating Custom Exceptions (Visual Basic .NET)
Namespace hks Module UseCustomExceptions Public Sub Main() Try Dim big_discount as new Discount(56) Catch ex as Exception Console.WriteLine(ex.Message) End Try End Sub End Module Public Class Discount Private percent as Integer Public Sub New(ByVal percent as Integer) Me.percent = percent If (percent > 50) Then Throw New TooBigDiscountException("Discount > 50%") End If End Sub End Class Public Class TooBigDiscountException Inherits Exception Public Sub New(ByVal msg as String) MyBase.New(msg) End Sub End Class End Namespace
Delegates
New to Visual Basic .NET is the capability of using delegates or function pointers (Listing 3.15).
Listing 3.15 Using Delegates (Visual Basic .NET)
Imports System Namespace hks Module Use Delegates Delegate Sub MyDelegate(ByVal msg as String) Public Sub Main() Dim msg As String = "Hello Delegates" Dim d1 as MyDelegate = AddressOf PrintOnce Dim d2 as MyDelegate = AddressOf PrintTwice d1(msg) d2(msg) End Sub Public Sub PrintOnce(ByVal msg as String) Console.WriteLine(msg) End Sub Public Sub PrintTwice(ByVal msg as String) Console.WriteLine("1." & msg) Console.WriteLine("2." & msg) End Sub End Module End Namespace
Events
Visual Basic developers have traditionally enjoyed the benefits of an easy-to-use event-handling system (Listing 3.16).
Listing 3.16 Using Events (Visual Basic .NET)
Imports System Namespace hks Module Events Friend WithEvents button As Button Public Sub Main() button = New Button() button.Click End Sub Public Sub Button_OnClick Handles button.OnClick Console.WriteLine("Button Clicked") End Sub End Module Public Class Button Public Event OnClick Public Sub Click() RaiseEvent OnClick() End Sub End Class End Namespace
Visual J#
With Visual Studio, Microsoft introduced the Visual J++ programming language and development tool. Visual J++ provided Java-based application development on the Microsoft Windows platform. Programs and components developed with Visual J++ executed on the Microsoft Java Virtual Machine. Visual J#, however, is quite different because it provides for Java-based programs to be compiled into .NET components and applications using MSIL. Therefore, the J# programming language is really like C# or Visual Basic .NET, but the programming language syntax is that of the Java programming language. J# still has all the benefits of the Java programming language as a simplified object-oriented programming language (no pointers, and so on). It is based on JDK 1.1.4.
Why J#? - J# was introduced by Microsoft to leverage the large pool of skills available through Java developers worldwide and provide them with the capability to utilize their existing skills and language experience to develop .NET applications.
Using the Visual J# programming language, existing Java developers can do the following:
- Utilize the knowledge of Java programming for .NET application development
- Support JDK 1.1.4 Class Library and most JDK 1.2
java.util
class libraries - Utilize extensions to the Java programming language for properties, delegates, and events
- Convert existing Visual J++ projects to Visual J# using the Project Import Wizard
- Create Javadoc-based documentation
- Provide support for applets, like the deployment model, known as J# Browser Controls
Hello World
A simple Hello World J# application looks pretty much like a typical Java application. The only difference is the use of the .NET Framework class library (System.Console.WriteLine
) instead of the typical Java System.out.println
. Java supports the notion of namespaces through packages, and that has been incorporated into J# for .NET namespaces. Also, Java provides the capability of using external class libraries with the import
keyword. This has also been utilized with J# as well. (Note: J# requires a ".*" to be attached to the namespace.)
package hks; import System.*; public class HelloWorld { public static void main() { Console.WriteLine("Hello World in J#"); } }
J# programs are stored with the .jsl extension. To compile a J# application, use the .NET J# compiler, vjc.exe.
vjc HelloWorld.jsl
Comments
In addition to the single-line and multiline comments that are similar to those of C#, J# also supports and extends the traditional Javadoc-style comments. (For non-Java programmers, Javadoc-style comments are special comments similar to XML comments in C#, used to automatically generate HTML documentation from Java programs.)
package hks; import System.*; public class Comments { public static void main() { // A Simple Comment /* A multi line comment */ Console.WriteLine("Hello World in J#"); } }
Data Types
Table 3.3 shows how the Visual J# types map to the corresponding .NET Framework types.
Table 3.3 Visual J# Data Types
Visual J# Type | Corresponding .NET Framework Type |
boolean | System.Boolean |
byte | System.Byte , System.SByte |
char | System.Char |
double , float | System.Double , System.Single |
short , int , long | System.Int16 , System.Int32 , System.Int64 |
Object | System.Object |
String | System.String |
Enumerations
J# doesn't support the creation of enumerations. However, the language does provide the capability to utilize enumerations that have been already defined in the .NET Framework or any custom .NET assemblies. Enumerations are treated as reference types as well.
Arrays
As shown in the program that follows, using arrays is very similar to C#. Notice the get_Length()
method used to get an array's length, as properties are not supported in J#.
package hks; import System.*; public class UseArrays { public static void main() { String[] days_of_week = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; for (int i=0;i<days_of_week.get_Length();i++) { Console.WriteLine(days_of_week[i]); } } }
Variables and Constants
Constants in J# are prefixed by the final
keyword. All the other mechanisms of creating new value types and reference types are similar to those of C#.
package hks; import System.*; public class UseVariables { public static void main() { final String HELLO_WORLD = "Hello World"; String message = HELLO_WORLD + " in VJ#"; MyClass mc = new MyClass(message); mc.Print(); } } public class MyClass { private String message; public MyClass(String message) { this.message = message; } public void Print() { Console.WriteLine(message); } }
Expressions
Basic expressions in J# are very similar to those in C#.
package hks; import System.*; public class UseExpressions { public static void main() { int a = 10; int b = 10; int result = a*10; boolean check = (a==b); Console.WriteLine(result); Console.WriteLine(check); } }
Statements
Statements in J# are very similar to those in C#.
package hks; import System.*; public class UseStatements { public static void main() { String[] message = {"Hello","World","in","VJ#"}; for (int i=0;i<message.get_Length();i++) { Console.Write(message[i]+" "); } int a = 10; int b = 10; if (a<b) { Console.WriteLine("a<b"); } else { Console.WriteLine("a>=b"); } } }
Classes
Constructs such as class definition, abstract classes, inheritance, and so on in J# are all very similar to C# (Listing 3.17). However, properties are not supported within the Java programming language; this is carried on with J#. But J# does support properties using the property accessor methods (set_
, get_
).
Listing 3.17 Using Classes (Visual J#)
package hks; import System.*; public class Useclasses { public static void main() { Person hs = new Person("Hitesh","Seth"); Person jd = hs; jd.set_FirstName("John"); jd.set_LastName("Doe"); Console.WriteLine(hs.GetFullName()); } } public class Person { private String sFirstName, sLastName; public Person(String FirstName, String LastName) { this.sFirstName = FirstName; this.sLastName = LastName; } public void set_FirstName(String FirstName) { this.sFirstName = FirstName; } public String get_FirstName() { return sFirstName; } public void set_LastName(String LastName) { this.sLastName = LastName; } public String get_LastName() { return sLastName; } public String GetFullName() { return sFirstName +"."+sLastName; } }
Similar to C#, J# also supports single inheritance, including overriding base class methods (Listing 3.18). However, unlike C#, all nonprivate methods can be overridden by a derived class. In essence, then, J# methods behave like virtual methods.
Listing 3.18 Inheriting Classes (Visual J#)
package hks; import System.*; public class UseInheritance { public static void main() { FullPerson hs = new FullPerson("Hitesh","K","Seth"); Console.WriteLine(hs.GetFullName()); Object oHs = hs; if (oHs instanceof Person) { Console.WriteLine("I am still a Person"); } } } public class Person { public String FirstName, LastName; public Person(String FirstName, String LastName) { this.FirstName = FirstName; this.LastName = LastName; } public String GetFullName() { return FirstName + "." + LastName; } } public class FullPerson extends Person { public String MiddleInitial; public FullPerson(String FirstName, String MiddleInitial, String LastName) { super(FirstName,LastName); this.MiddleInitial = MiddleInitial; } public String GetFullName() { return FirstName + "." + MiddleInitial + "." + LastName; } }
Abstract classes are supported in a way similar to C# (Listing 3.19).
Listing 3.19 Using Classes (Visual J#)
package hks; import System.*; public class UseAbstractClasses { public static void main() { Person hs = new Person("Hitesh","Seth"); Console.WriteLine(hs.GetFullName()); } } public abstract class Abstract { protected String FirstName, LastName; public Abstract(String FirstName, String LastName) { this.FirstName = FirstName; this.LastName = LastName; } abstract public String GetFullName(); } public class Person extends Abstract { public Person(String FirstName, String LastName) { super(FirstName, LastName); } public String GetFullName() { return FirstName+"."+LastName; } }
Interfaces
With constructs very similar to C#, the J# programming language also supports multiple inheritance using Interfaces (Listing 3.20). Actually, the simple mechanism of interface was in some sense introduced by Java and adopted by C#.
Listing 3.20 Using Interfaces (Visual J#)
package hks; import System.*; public class UseInterfaces { public static void main() { Person hs = new Person(); hs.set_Name("Hitesh Seth"); hs.set_Address("1 Executive Driver, City, NJ 08520"); Console.WriteLine(hs.GetName()); Console.WriteLine(hs.GetAddress()); } } public interface IName { public String GetName(); } public interface IAddress { public String GetAddress(); } public class Person implements IName, IAddress { private String name, address; public Person() { } public void set_Name(String value) { name = value; } public void set_Address(String value) { address = value; } public String GetName() { return name; } public String GetAddress() { return address; } }
Exception Handling
Exception handling has always been supported in the Java programming language, and that capability is easily reused with the .NET exception model as well.
package hks; import System.*; public class UseExceptions { public static void main() { try { int a = 10; int b = 10; int c = a/(a-b); } catch (System.Exception ex) { Console.WriteLine("Exception Caught"); Console.WriteLine(ex.get_Message()); } } }
Custom exceptions are supported in J#, again, this is very similar to C# (Listing 3.21).
Listing 3.21 Creating Custom Exceptions (Visual J#)
package hks; import System.*; public class UseCustomExceptions { public static void main() { try { Discount big_discount = new Discount(56); } catch (TooBigDiscountException ex) { Console.WriteLine("Exception Caught"); Console.WriteLine(ex.get_Message()); } } } public class Discount { private int percent; public Discount(int percent) throws TooBigDiscountException { this.percent = percent; if (percent > 50) throw new TooBigDiscountException("Discount > 50%"); } } public class TooBigDiscountException extends System.Exception { public TooBigDiscountException(String msg) { super(msg); } }
Delegates and Events
Because the Java programming language has no built-in support for delegates and events, the J# implementation provides a set of extensions for creating this capability. Delegates are tagged with a special comment /** @delgate */
before its definition and so are events (using /** @event */
). Also, the class implementing the events needs to keep a reference to all the listeners assigned for the particular events by creating an ArrayList
or a similar collection. After the listeners have been assigned, they are invoked using the Invoke
method (Listing 3.22).
Listing 3.22 Using Delegates and Events (Visual J#)
package hks; import System.*; import System.Collections.*; /** @delegate */ public delegate void EventHandler(); public class Button { ArrayList listeners = new ArrayList(); public static void main() { Button button = new Button(); button.add_OnClick(new EventHandler(Button_OnClick)); button.Click(); } /** @event */ public void add_OnClick(EventHandler listener) { listeners.Add(listener); } /** @event */ public void remove_OnClick(EventHandler listener) { listeners.Remove(listener); } public void Click() { Object [] olisteners = listeners.ToArray(); for (int i = 0;i < olisteners.length ;i++) { ((EventHandler)(olisteners[i])).Invoke(); } } public static void Button_OnClick() { Console.WriteLine("Button Clicked"); } }
Managed C++
Managed C++ doesn't really represent a separate programming language. A number of features introduced by the .NET Framework aren't supported through the standard C++ programming language, Visual C++ 2003, also better known as Managed C++. Managed C++ extensions represent an additional set of keywords that provide the necessary extensions to C++ for development of .NET constructs.
Called a power-oriented programming language, Visual C++ .NET provides .NET application developers the ultimate combination of power, control, and performance-centric bridging of the native and managed code environments. Key highlights of the Visual C++ .NET programming language include:
- Utilization of Win32/local Windows and CLR environments together
- Continued support of Standard ISO C++ for portability across C++ implementation environments
- Support for advanced C++ features such as templates, pointers, and intrinsic features (such as processor-specific instructions)
- A highly optimizing compiler with support for 32/64 bit microprocessors
- Advanced error reporting and debugging
Hello World
#using <mscorlib.dll> using namespace System; void main() { Console::WriteLine(S"Hello World in Managed C++"); }
Compiling a Managed Extensions–enabled C++ program requires using the /CLR compiler option, which indicates to the compiler that the C++ programs must be compiled into a .NET assembly.
cl /CLR HelloWorld.cpp
Managed Extensions
Table 3.4 provides a quick list of key managed extensions to the C++ programming language.
Table 3.4 Key Managed C++ Extension Keywords
Managed C++ Extension | Description |
__gc | Indicates that the struct/class identified is managed (garbage collected) |
__value | Indicates a value type |
__interface | Interface |
__delegate | Delegates |
__event | Events |
__property | Properties |
__abstract | Abstract classes: Must be derived for creating instances |
__sealed | Sealed (Final) class: cannot be derived |
__identifier | Use C++ keyword as an identifier |
__typeof | Provides access to type of the object |
__try_cast | Provides a dynamic checked cast |
To create a managed class (which means that no allocation is required), prefix the __gc
keyword to a C++ class definition. This indicates to the C++ compiler that what is going to be declared is a managed C++ class (Listing 3.23).
Listing 3.23 Creating Managed Classes (Managed C++)
#using <mscorlib.dll> namespace hks { __gc class Person { public: System::String* FirstName; System::String* LastName; Person(System::String* FirstName, System::String* LastName) { this->FirstName = FirstName; this->LastName = LastName; } }; }; void main() { hks::Person* p1 = new hks::Person(S"Hitesh",S"Seth"); hks::Person* p2 = p1; p1->FirstName = S"John"; p2->LastName = S"Doe"; System::Console::WriteLine("{0}.{1}",p1->FirstName,p1->LastName); System::Console::WriteLine("{0}.{1}",p2->FirstName,p2->LastName); }
Listing 3.24 is another example of using managed extensions, this time to create events and delegates.
Listing 3.24 Using Events and Delegates Managed Extensions (Managed C++)
#using <mscorlib.dll> namespace hks { __delegate void MyDelegate(System::String *msg); __gc class HelloWorld { public: void PrintOnce(System::String *msg) { System::Console::WriteLine(msg); } void PrintTwice(System::String *msg) { System::Console::WriteLine("1.{0}",msg); System::Console::WriteLine("2.{0}",msg); } }; }; int main() { hks::HelloWorld* hw = new hks::HelloWorld(); System::String *msg = S"Hello Delegates"; hks::MyDelegate *d1 = new hks::MyDelegate(hw,&hks::HelloWorld::PrintOnce); hks::MyDelegate *d2 = new hks::MyDelegate(hw,&hks::HelloWorld::PrintTwice); d1->Invoke(msg); d2->Invoke(msg); }
Other .NET Programming Languages
If you thought support for four programming languages (C#, Visual Basic .NET, C++, and J#) made .NET programming flexible, you haven't realized the whole story yet. Because every program will end up in MSIL and then be executed later by the CLR, it is possible to write a compiler for practically any programming language, whether it supports object-oriented constructs, functional programming constructs, modular programming constructs, or plain-old procedural constructs, so that it can be compiled into MSIL. This has been the drive behind extensive third-party programming language support for .NET. Chances are that if you know a programming language, it has already been ported to .NET. This goes for APL, COBOL, Delphi, Eiffel, Fortran, Forth, Haskell, Prolog, Pascal, Perl, Python, Scheme, and so on. As you can see, the CLR allows developers to utilize their skills in whatever programming language they have and apply them to the .NET environment. Applying COBOL skills to .NET means that you can develop rich Windows forms applications, Web applications, or even Web services using COBOL. These are programming constructs that were never thought about when these languages were designed originally. It is really because of the richness and flexibility of the CLR that such a thing is possible.
Microsoft research itself has been quite active when it comes to designing and implementing new programming languages for .NET. ASML (Abstract State Machine Language), F# (an implementation of the Caml programming language), and SML.NET (an implementation of the Standard ML) are some of the initiatives from Microsoft research, exploring newer programming models with .NET.
Languages come and go; third-generation programming languages will evolve into fourth-generation programming languages, and so on. With the CLR, the .NET programming model is set to evolve with this change and also utilize the technology excellence and research in the computer science community.
An updated list of .NET programming languages is available at http://www.jasonbock.net/dotnetlanguages.html.
Interoperating with Different Programming Languages
The objective of this section is to illustrate that .NET really supports cross-programming language use. You will learn how classes defined in one programming language can be subclassed in another and utilized in yet another. First, define the Base
class in C#.
using System; namespace mixed { public class Base { public Base() { } public virtual String GetLanguage() { return "C#"; } } }
This program is compiled into a library using the C# compiler.
csc /t:library CSharp.cs
Next, a Visual Basic .NET class is declared as a subclass of the Base
class.
Imports System Namespace mixed Public class Derived Inherits Base Public Sub New() End Sub Public Overrides Function GetLanguage() As String return "Visual Basic .NET" End Function End Class End Namespace
To compile the Visual Basic program, the Visual Basic .NET compiler is invoked, passing the reference to the previously created base class assembly.
vbc /reference:CSharp.dll /target:library VBasic.vb
Now you eventually develop a Java class that actually uses the classes defined earlier. The Java class has a main
method and so can be compiled into an executable.
vjc /reference:CSharp.dll,VBasic.dll VJSharp.jsl
The program VJSharp.exe can be executed to get the results:
Visual Basic .NET Derived is an instance of Base
This small exercise should remove any doubts regarding the .NET interoperability of the various programming languages.
Selecting the Right Programming Language - The .NET programming model provides developers a true choice when selecting a programming language to implement an application or when creating a component library. Selecting the language to use primarily depends on your existing skills and is your personal choice. If you are a Visual Basic programmer, you will probably pick Visual Basic .NET. If you are a C++ programmer, you will either continue with Visual C++ .NET or consider C# as your major programming language. If you have come from a Java programming background, you will probably end up with either Visual J# or Visual C#. Another factor that would influence the choice of programming language is ubiquity and market demand in your area. For instance, currently the New York City metropolitan area (where I live) seems to be headed in the C# direction, based on its high C++ influence. Although it is definitely possible to mix different programming languages in a single solution, in my opinion, it is rarely done. In many ways, different programming languages can be utilized to achieve similar results; sometimes the choice of a language is influenced by what sort of application is being written. For instance, Perl might be an excellent candidate for a bunch of .NET components that do heavy pattern matching and text processing. In a nutshell, when you select a programming language, you should look at your existing skills and combine them with the programming constructs provided to you by the different languages to make an informed decision.
In Brief
- The .NET Framework programming model provides the developer with a true choice when it comes to selecting a programming language for a .NET application, Web services, or a component.
- C#, Visual Basic, C++, and J# are the four main programming languages for .NET, at least out of the box with the Framework and the Visual Studio .NET tool.
- Whereas C# represents the most modern, current, and innovative programming language, Visual Basic .NET stands for high ease of use and developer productivity. C++ provides .NET developers immense power, especially when it comes to lower-level operating systems, Win32 API access, and the most efficient interoperability with existing applications and components. J# provides Java developers with the ease of moving into the .NET programming model.
- A number of ISVs have ported various programming languages to output MSIL for the CLR.
- Choosing the right programming language primarily depends on your existing skills and the usage. For instance, C++ would be the language of choice for efficient interoperability with the Windows operating system APIs and existing applications.
License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)