I've been looking at return values for Type.Namespace
, Type.Name
, Type.FullName
, and Type.AssemblyQualifiedName
. There are inconsistencies.
For an inner class like ConsoleApplication8.Program+InnerClass
, Namespace returns ConsoleApplication8
and Name
returns InnerClass
, omitting Program
, so concatenating Type.NameSpace
and Type.Name
would be an incomplete representation of the class name (just as an example).
Even the FullName
property is inconsistent. Although it omits assembly name and returns ConsoleApplication8.Program+InnerClass
for such an inner class, FullName
includes the assembly name in the generic arguments for a type such as List<long>
(even though it's omitted for the outer generic type itself, so I guess there is some level of consistency there).
I am currently using this code with a cached type name lookup that uses the CodeDom to produce real C# code names. Basically, I'm trying to reverse the process to get the type, given a real class name.
static System.Collections.Concurrent.ConcurrentDictionary<Type, string> typeNameCache = new System.Collections.Concurrent.ConcurrentDictionary<Type, string>();
static string GetTypeName(Type type)
{
string name;
if (!typeNameCache.TryGetValue( type, out name ))
{
var codeDomProvider = CodeDomProvider.CreateProvider("C#");
var typeReferenceExpression = new CodeTypeReferenceExpression(new CodeTypeReference(type));
using (var writer = new StringWriter())
{
codeDomProvider.GenerateCodeFromExpression(typeReferenceExpression, writer, new CodeGeneratorOptions());
name = writer.GetStringBuilder().ToString();
}
typeNameCache.TryAdd( type, name );
}
return name;
}
The above function produces friendly C# name like System.Collections.Generic.List<long>
. But it also produces names like ConsoleApplication8.Program.InnerClass
(i.e. it uses a dot instead of a plus sign between Program
and InnerClass
). The problem is that calling Type.GetType(name)
won't work, because it would require the plus sign to be there, and in addition it sometimes requires the assembly name.
So how can I get a references to a Type
object, given a friendly C# class name as it would be referenced in code?