views:

454

answers:

2

Hello,

is there a function that, given a C# type's string representation, returns the corresponding .Net type or .Net type's string representation; or any way to achieve this.

For example :

"bool" -> System.Boolean or "System.Boolean"

"int" -> System.Int32 or "System.Int32"

...

Thanks.

Edit : really sorry, it's not a "type to type" mapping that I wish but either a "string to string" mapping or a "string to type" mapping.

+1  A: 

Your question isn't entirely clear: I'm not sure what form you've got for the C# alias. If you know it at compile time, you can use typeof() as normal - the C# aliases really are just aliases, so typeof(int) == typeof(System.Int32). There's no difference in the code emitted.

If you've got a string, e.g. "int", just build a map:

Dictionary<string,Type> CSharpAliasToType = new Dictionary<string,Type>
{
    { "string", typeof(string) },
    { "int", typeof(int) },
    // etc
};

Once you've got the Type you can get the full name, the assembly etc.

Here's some sample code which takes into account nullable types:

public static Type FromCSharpAlias(string alias)
{
    bool nullable = alias.EndsWith("?");
    if (nullable)
    {
        alias = alias.Substring(0, alias.Length - 1);
    }
    Type type;
    if (!CSharpAliasToType.TryGetValue(alias, out type))
    {
         throw new ArgumentException("No such type");
    }
    return nullable ? typeof(Nullable<>).MakeGenericType(new Type[]{ type })
                    : type;
}
Jon Skeet
The mapping with a dictionary is what I've done so far, but it's heavy and difficult to maintain.Moreover I would like the automatic lookup of nullable types :"bool?" -> System.Nullable`1[System.Boolean]
Serious
In what way is it "heavy" or difficult to maintain? There's not really going to be any maintenance, surely, unless the C# team add a new type alias, which I think is very unlikely. (I wouldn't include `dynamic` in there for C# 4 as that doesn't constitute a real CLR type.) As for "?" - just check whether the string ends with it or not... (Will provide sample code.)
Jon Skeet
+3  A: 

The list of built-in types in C# is quite short and not very likely to change, so I think having a dictionary or a big switch statement to map these shouldn't be difficult to maintain.

If you want to support nullable types, I believe you have no other option than to parse the input string:

static Type GetTypeFromNullableAlias(string name)
{
    if (name.EndsWith("?"))
        return typeof(Nullable<>).MakeGenericType(
            GetTypeFromAlias(name.Substring(0, name.Length - 1)));
    else
        return GetTypeFromAlias(name);
}

static Type GetTypeFromAlias(string name)
{
    switch (name)
    {
        case "bool": return typeof(System.Boolean);
        case "byte": return typeof(System.Byte);
        case "sbyte": return typeof(System.SByte);
        case "char": return typeof(System.Char);
        case "decimal": return typeof(System.Decimal);
        case "double": return typeof(System.Double);
        case "float": return typeof(System.Single);
        case "int": return typeof(System.Int32);
        case "uint": return typeof(System.UInt32);
        case "long": return typeof(System.Int64);
        case "ulong": return typeof(System.UInt64);
        case "object": return typeof(System.Object);
        case "short": return typeof(System.Int16);
        case "ushort": return typeof(System.UInt16);
        case "string": return typeof(System.String);
        default: throw new ArgumentException();
    }
}

Test:

GetTypeFromNullableAlias("int?").Equals(typeof(int?)); // true
dtb