views:

159

answers:

5

I want to convert a C# style generic type string, like

"System.Dictionary<System.String, System.String>"

to it's CLR equivalent:

"System.Dictionary`1[System.String, System.String]"

and back. Is there an easy way to do this, or do I have to resort to string manipulation?

EDIT: I only have the string representation in C#/VB/etc style form. I don't have a Type object or something similar at hand. An alternate question would have been: how to get a Type object from a string representation like "System.Dictionary<System.String, System.String>" (after that I can get the full name of the type object)

EDIT2: justification: I'm creating objects dinamically using CodeDom. The input from which I'm generating the CodeDom might contain types in C# (or any other proprietary like VB.NET) format, but I have to use them inside a CodeTypeReference, which only accepts the CLR style format.

A: 
typeof(System.Dictionary<System.String>, System.String>).FullName

As for the reverse, no clue :(

Aren
A: 

I am not sure I completely understand your question. Anyway -when you instantiate a genetic class Class<T1, ... ,Tn> the defined in namespace Namespace, for example

Namespace.Class<T1, ... ,Tn> a = new Namespace.Class<Type1,...,Typen>();

a.GetType().FullName will give you the full string representation of the class which will be "Namespace.Class'n<Type1,...,Typen>"

Itay
A: 

typeof(System.Dictionary<System.String, System.String>).FullName should get you something like:

System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

Might need to do some replacement on the full type names inside the type parameter spec. However if you use the below code

typeof(Dictionary<System.String, System.String>).ToString()

You will get something like this:

System.Collections.Generic.Dictionary`2[System.String,System.String]

To convert back into a Type use

Type.GetType("System.Collections.Generic.Dictionary`2[System.String,System.String]");

EDIT I've tried hacking this with dynamic expressions but didn't have much luck. I think, other than parsing the string, you can use a "nuclear option" and compile a DLL using CSharpCodeProvider and then load it using Assembly.LoadFile and execute a method that will evaluate typeof(...).

Igor Zevaka
I only have the string representation of the type in C# style. See edit.
SztupY
Hmm. Not something one would want to do normally. If you have C# code, you compile it. If you have string representation of a type, it's normally serialised to string and then deserialised. Both of those cases are supported by the framework. Could you provide more context about what you are doing?
Igor Zevaka
for context see edit2.
SztupY
A: 

I think this is what you were looking for...

var dict = new Dictionary<string, string>();
var type = dict.GetType();
var typeName = type.FullName;
var newType = Type.GetType(typeName);

Console.WriteLine(type == newType); //true
Matthew Whited
I only have the string representation of the type in C# style
SztupY
@SztupY: If you want to make an instance of the object/type you may be able to use CodeDom instead of string manipulation. But you best bet would probably be to write some sort of converter/parser for the string values. It is an option to replace the `C#` style values with the correct `Type.FullName` or `Type.AssemblyQualifiedName`?
Matthew Whited
CodeDOM reference link... http://msdn.microsoft.com/en-us/library/f1dfsbhc.aspx
Matthew Whited
+2  A: 

For the .NET to C# direction, I can't see an easy way to do it; you may have to actually parse the type yourself.

In the other direction, it's pretty easy:

public static string DotNetToCSharp(string tyName) {
    var provider = new Microsoft.CSharp.CSharpCodeProvider();
    return provider.GetTypeOutput(new System.CodeDom.CodeTypeReference(tyName));
}
kvb
for the other way it seems i have to resort to codesnippets (or parse it by hand)
SztupY