Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to get a proper type name from a C# keyword?

Tags:

c#

I want to create a type using Type.GetType( nameOfTheType ), where nameOfTheType is some string. If nameOfTheType is "System.String", this works great. If nameOfTheType is "string", this throws an exception. All types with keyword shortcuts fail.

Is there a way, other than a big switch statement, to correctly map all of the types with keyword shortcuts to their actual type names (as per this list: http://msdn.microsoft.com/en-us/library/ya5y69ds%28VS.80%29.aspx)?

Edit: Gabriel has correctly pointed out that the MSDN page I linked does not include nullable types (int?, etc.), but it is important that nullable types are mapped correctly as well.

like image 508
Greg Smalter Avatar asked Nov 03 '09 00:11

Greg Smalter


1 Answers

Disclaimer
Let me start out by saying that the method I'm going to demonstrate here is purely for educational purposes. Please use the switch or dictionary lookups demonstrated in the other answers in your production code.

Answer
So, the only way to find out how the compiler would interpret a given piece of code is to actually compile it and inspect the generated assembly. This isn't so hard to do in .NET... You could compile an arbitrary string during runtime using the C# compiler like so:

private static Type GetTypeByFullNameOrAlias(string typeName)
{
  Type type = Type.GetType(typeName);

  if (type == null)
  {
    using (var provider = new CSharpCodeProvider())
    {
      var compiler = provider.CompileAssemblyFromSource(
        new CompilerParameters
          {GenerateInMemory = true, GenerateExecutable = false, IncludeDebugInformation = false},
        "public class A { public " + typeName + " B; }");

      type = ((FieldInfo)compiler.CompiledAssembly.GetType("A").GetMember("B")[0]).FieldType;
    }
  }

  return type;
}

However, this technique has several drawbacks... First of all it is slow. Of course you could cache the result and do other trickery to speed up the process. But there's another problem, which is that it compiles and loads a complete assembly each time it reaches the inside of the "if" statement. Each assembly it loads cannot be unloaded again and will hang around until the application closes, so this technique will also leak a small amount of memory. Again, you could load the generated assembly into an separate AppDomain and unload the domain after you've inspected the type but that would only make the code a lot slower.

But as I pleaded in the beginning, just use the "switch" solution in your production code... It does a perfectly good job of translating the aliases. And it's not like they're going to change those language aliases anytime soon.

like image 87
JohannesH Avatar answered Oct 05 '22 23:10

JohannesH