.NET differentiates between reference types and value types. With C# reference types are defined with classes, and value types with structs. Besides how to create reference and value types, this chapter also shows how to define an interface (a reference type) and an enumeration (a value type).
To declare a reference type, C# and Visual Basic use the class keyword. In C++/CLI a class and a struct are nearly the same; you don’t have the separation between a reference type and a value type as you do with C# and Visual Basic. C++/CLI has a ref keyword to define a managed class. You can create a reference type by defining ref class or ref struct.
Both with C# and C++/CLI the class is surrounded by curly brackets. With C++/CLI don’t forget the semicolon at the end of the class declaration. Visual Basic uses the End Class statement at the end of the class.
// C# public class MyClass { } // C++/CLI public ref class MyClass { }; public ref struct MyClass2 { }; ' Visual Basic Public Class MyClass End Class
When using a reference type a variable needs to be declared, and the object must be allocated on the managed heap. When declaring a handle to a reference type, C++/CLI defines the handle operator ^ that is somewhat similar to the C++ pointer *. The gcnew operator allocates the memory on the managed heap. Using C++/CLI it is also possible to declare a variable locally, but for reference types the object is still allocated on the managed heap. With Visual Basic the variable declaration starts with the statement Dim followed by the name of the variable. With new and the object type, memory is allocated on the managed heap.
// C# MyClass obj = new MyClass(); // C++/CLI MyClass^ obj = gcnew MyClass(); MyClass obj2; ' Visual Basic Dim obj as New MyClass()
If a reference type does not reference memory, all three languages use different keywords: C# defines the null literal, C++/CLI nullptr (NULL is only valid for native objects), and Visual Basic Nothing.
Predefined reference types are listed in the following table. C++/CLI does not define the object and string type as is done with the other languages. Of course, you can use the classes defined by the Framework.
.NET Type | C# | C++/CLI | Visual Basic |
---|---|---|---|
System.Object | object | not defined | Object |
System.String | string | not defined | String |
To declare a value type, C# uses the struct keyword; C++/CLI, the keyword value; and Visual Basic, Structure.
// C# public struct MyStruct { } // C++/CLI public value class MyStruct { }; ' Visual Basic Public Structure MyStruct End Structure
With C++/CLI you can allocate a value type on the stack, on the native heap by using the new operator and on the managed heap by using the gcnew operator. C# and Visual Basic do not have these options, but these options become important when native and managed code is mixed with C++/CLI.
// C# MyStruct ms; // C++/CLI MyStruct ms1; MyStruct* pms2 = new MyStruct(); MyStruct^ hms3 = gcnew MyStruct(); ' Visual Basic Dim ms as MyStruct
Predefined value types for the different languages are listed in the following table. In C++/CLI the char type has just a size of 1 byte for an ASCII character. In C# char has a size of 2 bytes for Unicode characters; that’s a wchar_t in C++/CLI. The ANSI standard for C++ just defines short <= int <= long. With 32-bit machines, int and long both have a size of 32 bits. To define a 64-bit variable in C++, you need long long.
.NET Type | C# | C++/CLI | Visual Basic | Size |
---|---|---|---|---|
Char | char | wchar_t | Char | 2 bytes |
Boolean | bool | bool | Boolean | 1 byte, contains true or false |
Int16 | short | short | Short | 2 bytes |
UInt16 | ushort | unsigned short | UShort | 2 bytes with no sign |
Int32 | int | int | Integer | 4 bytes |
UInt32 | uint | unsigned int | UInteger | 4 bytes with no sign |
Int64 | long | long long | Long | 8 bytes |
UInt64 | ulong | unsigned long long | ULong | 8 bytes with no sign |
Defining interfaces is very similar with all three languages. All languages use the keyword interface:
// C# public interface IDisplay { void Display(); } // C++/CLI public interface class IDisplay { void Display(); }; ' Visual Basic Public Interface IDisplay Sub Display End Interface
Implementing interfaces is different. C# and C++/CLI use a colon after the class name followed by the interface name. The methods defined with the interface are implemented. With C++/CLI, the methods must be declared virtual. Visual Basic uses the Implements keyword to implement an interface, and the methods that are defined by the interface also need the Implements keyword attached.
// C# public class Person : IDisplay { public: void Display() { } } // C++/CLI public ref class Person : IDisplay { public: virtual void Display(); }; ' Visual Basic Public Class Person Implements IDisplay Public Sub Display Implements IDisplay.Display End Sub End Class
Enumerations are defined similarly in all three languages with the enum keyword (only Visual Basic uses a new line instead of a comma to separate the elements).
// C# public enum Color { Red, Green, Blue } // C++/CLI public enum class Color { Red, Green, Blue }; ' Visual Basic Public Enum Color Red Green Blue End Enum