The Hidden C# "Typedef"
I’ve just seen a blog entry about C# generics, concerning C#’s lack of typedefs. Actually, C# has a way of aliasing classes, using the using directive:
using IntList = System.Collections.Generic.List<int>;
IntList = System.Collections.Generic.List<int>;
Quite simple. This has been there since version 1, but it wasn’t quite useful until now.
Creating empty classes as suggested in the above link is a bad idea, in my opinion. You have to maintain them, and it can be awkward for interoperating assemblies (think of two assemblies defining different “alias classes” for the same type.)
Edit: Also see this post at Eric Gunnerson’s blog.
7 Responses to The Hidden C# "Typedef"
Tags
.NET 4 Animation Async Axum Blog C# ClearType Cloud CLR CodeValue Contests Deep Zoom Experiments Generics Google Ink Lectures Modeling Personal Pivot Prism Programming Languages Prolog Reflector RTL Sela Silverlight The Arbel Network Themes Threading Tips Visual Studio WCF Windows 7 Windows 2003 Windows Azure Windows Forms Windows Phone Windows Vista Windows XP WPF XAML ZuneArchives
- June 2011
- November 2010
- August 2010
- July 2010
- June 2010
- March 2010
- December 2009
- November 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- November 2007
- September 2007
- June 2007
- May 2007
- February 2007
- November 2006
- October 2006
- February 2006
- August 2005
- February 2005
- August 2004
- July 2004
- June 2004
- May 2004






It doesn’t seem to be possible to use this feature nested ?
Or am I doing something wrong ?
Sample :
using IntList = System.Collections.Generic.List<int>;
using NestedIntList = System.Collections.Generic.List<IntList>;
No, you can’t nest using directives. I’ve become convinced that using it for generics should be discouraged. Just write List<int>!
It’s much clearer, and really not that much of extra code. Even List<List<int>> is just fine.
I’ve found that the necessity for #typedef in C# lies heavily in conjunction with the necessity for multi-file preprocessor #define’s and #if/else testing. Using the "using MyType = InherentType;" for each file doesn’t seem to be truly necessary – aesthetics not considered – but there are some rare occasions when it would be more convenient and more CTS-friendly to be able to #define SOMETHING in file1.cs and perform a #if SOMETHING in file2.cs …
but then the necessity for a #typedef increases. Think about how architecture-specific value types were used in C/C++. Consider…
#if _X86
using INT32 int
#elseif _X64
using INT32 short
#else
using INT32 long
#endif
Granted, System.Int16, System.Int32, and System.Int64 solved this particular problem, but when these #typedef’s are used like this, the data types are defined from [U]INT8 all the way up to [U]INT64 (and I’ve even seen INT128).
It just seems to me that the necessity for a #typedef in C# is more closely related to the ability to perform preprocessor testing across multiple source files.
This solution actually only works for one file at the time and only in the declared namespace. It doesn’t help you if all you really want is to define one type at one place and use it in several. I commonly run into this kind of problem when I want to define a List of something and use them in several places. The only option then is to define a class which inherits from that List, e.g.
public class IntList : List<int>
{
// write constructors here
}
That’s usually a bad idea, in my opinion. And writing IntList instead of List<int> just saves a couple of characters. It may come handy in cases where the type is a bit longer (e.g. Expression<Func<Func<int, string>, bool>>) – but what name would be more descriptive than the original?
I say – stick to the full name, don’t subclass unless it actually means something and use the using directive only when you have a name collision and you don’t want to write the full namespace every time.
What about WPF? Usage of generics in XAML is very limited and there is no easy way to define DataTemplate that uses a parametrized type.
Unfortunately `using` directive doesn’t solve this problem. Only solution I’ve found is to derive class from generic class and put parameters in base definition. But this is only partial solution because every time I must define all needed constructors and I cannot use any generic `struct`’s (deriving from value-type is forbidden).
Actually, there is an easy way to define a DataTemplate for a generic type, for example:
<DataTemplate DataType="{x:Type col:List`1[System.String]}">
<TextBlock Text="This is a List{string}" Foreground="Red" />
</DataTemplate>
A few notes:
1. The TypeExtension only resolves the namespace before the colon and passes a concatenation of it and the what's after the colon to Assembly.GetType(). So you cannot use the XAML namespace mapping for the type parameter (e.g. col:List`1[sys:String]).
2. You can always write your own type-parsing MarkupExtension for more complex scenarios.
3. You can implement a DataTemplateSelector. In many cases the DataTemplate.DataType is quite insufficient. The simplest example – it doesn't support inheritance; the type must exactly match the runtime type of the object.