My C# 4.0 Wishlist, Part 4 : Constant typeof() Expressions
Along with some of the hacks I introduced into ShinyDesign, there was a problem using a generic parameter as an enum – I couldn’t cast it back to an integral type, even System.UInt64, because T was not guaranteed to be an integral value (yet again why we should allow a type constraint, but I digress).
In any case, there have been cases where I’d like to, for instance, switch against a Type, particularly since incorporating generics. Consider:
1: switch (typeof(T).GetUnderlyingType())
2: {
3: case typeof(byte):
4: case typeof(sbyte):
5: break;
6: case typeof(short):
7: case typeof(ushort):
8: break;
9: case typeof(int):
10: case typeof(uint):
11: break;
12: case typeof(long):
13: case typeof(ulong):
14: break;
15: }
This is MUCH cleaner than the alternative, current implementation:
1: Type t = typeof(T).GetUnderlyingType();
2: if (t == typeof(byte) || t == typeof(sbyte))
3: { }
4: else if (t == typeof(short) || t == typeof(ushort))
5: { }
6: else if (t == typeof(int) || t == typeof(uint))
7: { }
8: else if (t == typeof(long) || t == typeof(ulong))
9: { }
So this is a working example of how the syntax would be cleaner by allowing us to use the typeof expression result as a constant value. If you’ve never tried this, the compiler complains. Given this code:
155: switch (t)
156: {
157: case typeof(int):
158: case typeof(uint):
159: break;
160: }
I get:
EnumTypeConverter.cs(155,21): error CS0151: A value of an integral type expected
EnumTypeConverter.cs(157,22): error CS0150: A constant value is expected
EnumTypeConverter.cs(158,22): error CS0150: A constant value is expected
I’m sure you’ve switched over a string, though – it’s one of the nice syntactical features of C#. You might be wondering why, if switching over a string is possible, then why not a Type?
Switching on a string doesn’t switch on a string – it shoots the strings into a Dictionary<string, int>, stores the offsets, and then uses a jump table with the IL switch instruction:
Yeah, obviously there’s a lot of opportunity to misuse the typeof expressions. But there are going to be legit uses, too, and honestly – if C# can have a compiler trick for strings, it can have a compiler trick for types. And let’s be honest – typeof() expressions aren’t ever going to return different values for the same app (that’s why people were locking types to synchronize across an AppDomain).
This – like the inability to constrain a type constraint to an enum – is an artificial constraint that really shouldn’t be there.
