SYSK 270: How to implement C++’s typedef in C#

C++’s typedef declaration creates a new name (an alias) that, within its scope, becomes a synonym for the type given by the type-declaration portion of the declaration. The syntax is as follows:

typedef type_declaration synonym;

 

For example, in C++ one could use the ulong as a shorter version of unsigned long and use it throughout the code by first using the typedef statement below:

typedef unsigned long ulong;

In contrast to the class, struct, union, and enum declarations, typedef declarations do not introduce new types — they introduce new names for existing types. That means, that you can’t define two overloaded methods – one using the original type and the other using the typedef-ed synonym…

C# does not support typedef in the traditional C/C++ sense, but you use the using keyword to create a synonym:

using synonym = type_declartion;

So, is it useful for C# and VB.NET developers? If you’re doing PInvoke and COM interop, then I think the answer is ‘Yes’; if not, then, in my opinion, in most cases, the benefits do not outweigh the confusion of introducing what’s seen as a new type.

Judge for yourself:

using RecordID = System.UInt64;

public void SomeMethod(RecordID recordID)

{

. . .

}

vs.

 

// I prefer this over the method above as it’s known type and it’s clear

// on what properties/methods are available…

public void SomeMethod(long recordID)

{

. . .

}

However, there are three cases when I think it’s a good practice (or, at least, is acceptable) to use this feature:

1. In a narrow scope (e.g. class scope), you create synonyms for very long and ugly names. E.g. if you need to create a collection of items sorted by date-time, which, in turn, is an item of another collection of items per location id, which is an item of a collection where item id is the key:

System.Collections.Generic.Dictionary<int, System.Collections.Generic.Dictionary<short, SortedList<DateTime, DataItem>>>

you could choose to keep typing all this generics’ definitions, or (since the scope is tight, i.e. less chance for confusion), simply typedef it:

using Items = SortedList<DateTime, DataItem>;

using DataItemValueCollection = System.Collections.Generic.Dictionary<short, SortedList<DateTime, DataItem>>;

using PerformanceDataCollection = System.Collections.Generic.Dictionary<int, System.Collections.Generic.Dictionary<short, SortedList<DateTime, DataItem>>>;

And from there on, use the shorter names like Items, DataItemValueCollection or PerformanceDataCollection…

2. There are some cases where you may want to “resurrect” the old types, like VB’s Money type:

using Money = System.Decimal;

or where the “new type” definition is well known, e.g.:

using Tick = System.Int64;

3. With the increasing availability of 64-bit Windows, if you’re doing Interop, you may need to create applications that can run on both 32-bit and 64-bit versions of Windows natively (not using WOW64, Windows-32-on-Windows-64, emulation).

Those of you who remember the 16 to 32 bit move might remember the “polymorphic” C++ data types like SIZE_T, TCHAR, LPARAM, WPARAM, etc.

In those cases, you may need to create your own polymorphic types, e.g.:

#if WIN32

    using Pointer = System.Int32;

    using HWND = System.Int32;

#else

    using Pointer = System.Int64;

    using HWND = System.Int64;

#endif