Reputation: 3624
I'm parsing some DLLs and I have to generate some code that will be compiled. For the moment, everything works but now, we have to handle Collections<> types and here is the problem. In the case of an ObservableCollection, we got the Type whose FullName is :
"System.Collections.ObjectModel.ObservableCollection`1[System.String]"
and considering that I'm dealing with objects (I can read anything from the DLL), the code generated should be :
var obj7 = (System.Collections.ObjectModel.ObservableCollection<System.String>) myParsedProperty; //This code will, then, be compiled + executed
So... is there a simple way to do it from the Type or do I have to do some heavy things on Strings ? (manipulating propType.Name .Namespace and .GetGenericArguments() ...)
Upvotes: 0
Views: 714
Reputation: 17848
Here is the simplest approach:
//...
Type type = typeof(IList<string>);
string definition = GetGenericTypeDefinitionString(type);
//definition is "System.Collections.Generic.IList<System.String>"
}
static string GetGenericTypeDefinitionString(Type genericType) {
string genericTypeDefName = genericType.GetGenericTypeDefinition().FullName;
string typePart = genericTypeDefName.Substring(0, genericTypeDefName.IndexOf('`'));
string argumentsPart = string.Join(",",
Array.ConvertAll(genericType.GetGenericArguments(), (t) => t.FullName));
return string.Concat(typePart, '<', argumentsPart, '>');
}
Also you can experiment with a Code.Dom:
using System.CodeDom;
using Microsoft.CSharp;
//...
Type targetType = typeof(IList<string>);
//...
CSharpCodeProvider provider = new CSharpCodeProvider();
CodeExpression cast = new CodeCastExpression(targetType, new CodeVariableReferenceExpression("genericCollection"));
CodeStatement statement = new CodeVariableDeclarationStatement(new CodeTypeReference(targetType), "list", cast);
using(StringWriter writer = new StringWriter()) {
provider.GenerateCodeFromStatement(statement, writer, null);
string expression = writer.ToString();
// expression is "System.Collections.Generic.IList<string> list = ((System.Collections.Generic.IList<string>)(genericCollection));"
}
Upvotes: 1