我怎样才能从string表示获得genericstypes?
我有MyClass<T>
。
然后我有这个string s = "MyClass<AnotherClass>";
。 我怎样才能从strings
获取Type?
一种方法(丑陋的)是parsing出“<”和“>”,并做:
Type acType = Type.GetType("AnotherClass"); Type whatIwant = typeof (MyClass<>).MakeGenericType(acType);
但有没有一个更清晰的方式来获得最终的types没有任何parsing等?
generics的格式是名称,字符,types参数的数量,后面跟着逗号分隔的括号中的types列表:
Type.GetType("System.Collections.Generic.IEnumerable`1[System.String]");
我不确定是否有一种简单的方法可以将generics的C#语法转换为CLR想要的stringtypes。 我开始写一个快速的正则expression式来parsing它,就像你在问题中提到的那样,但是意识到除非你放弃了嵌套generics作为types参数的能力,否则parsing将变得非常复杂。
查看Activator.CreateInstance
– 你可以用一个types来调用它
Activator.CreateInstance(typeof(MyType))
或者将一个程序集和types名称作为string
Activator.CreateInstance("myAssembly", "myType")
这会给你一个你需要的types的实例。
如果您需要Type
而不是实例,请使用Type.GetType()
方法和您感兴趣的types的完全限定名称,例如:
string s = "System.Text.StringBuilder"; Type myClassType = Type.GetType(s);
这会给你的Type
的问题。
我需要这样的东西,我写了一些代码来parsing我需要的简单types名称。 当然,还有改进的余地,因为它不会识别像List<string>
这样的genericstypes名称,但是它对string
, int[]
, decimal?
等等。 如果这有助于任何人共享。
public static class TypeExtensions { public static Type GetTypeFromSimpleName(string typeName) { if (typeName == null) throw new ArgumentNullException("typeName"); bool isArray = false, isNullable = false; if (typeName.IndexOf("[]") != -1) { isArray = true; typeName = typeName.Remove(typeName.IndexOf("[]"), 2); } if (typeName.IndexOf("?") != -1) { isNullable = true; typeName = typeName.Remove(typeName.IndexOf("?"), 1); } typeName = typeName.ToLower(); string parsedTypeName = null; switch (typeName) { case "bool": case "boolean": parsedTypeName = "System.Boolean"; break; case "byte": parsedTypeName = "System.Byte"; break; case "char": parsedTypeName = "System.Char"; break; case "datetime": parsedTypeName = "System.DateTime"; break; case "datetimeoffset": parsedTypeName = "System.DateTimeOffset"; break; case "decimal": parsedTypeName = "System.Decimal"; break; case "double": parsedTypeName = "System.Double"; break; case "float": parsedTypeName = "System.Single"; break; case "int16": case "short": parsedTypeName = "System.Int16"; break; case "int32": case "int": parsedTypeName = "System.Int32"; break; case "int64": case "long": parsedTypeName = "System.Int64"; break; case "object": parsedTypeName = "System.Object"; break; case "sbyte": parsedTypeName = "System.SByte"; break; case "string": parsedTypeName = "System.String"; break; case "timespan": parsedTypeName = "System.TimeSpan"; break; case "uint16": case "ushort": parsedTypeName = "System.UInt16"; break; case "uint32": case "uint": parsedTypeName = "System.UInt32"; break; case "uint64": case "ulong": parsedTypeName = "System.UInt64"; break; } if (parsedTypeName != null) { if (isArray) parsedTypeName = parsedTypeName + "[]"; if (isNullable) parsedTypeName = String.Concat("System.Nullable`1[", parsedTypeName, "]"); } else parsedTypeName = typeName; // Expected to throw an exception in case the type has not been recognized. return Type.GetType(parsedTypeName); } }
使用它就像写这个一样简单:
Type t; t = TypeExtensions.GetTypeFromSimpleName("string"); t = TypeExtensions.GetTypeFromSimpleName("int[]"); t = TypeExtensions.GetTypeFromSimpleName("decimal?");
要从string中获取types对象,请使用:
Type mytype = Type.GetType(typeName);
然后你可以传递给Activator.CreateInstance()
:
Activator.CreateInstance(mytype);
我没有太多的时间来parsing这个问题,不过我想我已经看到了类似的答案。 特别是,我认为他们正在做你想做的事情:
entity framework通用存储库错误
(String.Format("[{0}]", baseType.Name.ToString())).OfType<T>();
希望这有帮助,让我知道更具体的,如果这不是。