Tengo MyClass<T>
.
Y luego tengo esto string s = "MyClass<AnotherClass>";
. ¿Cómo puedo obtener Type de la cadena s
?
Una forma (fea) es analizar "<" y ">" y hacer:
Type acType = Type.GetType("AnotherClass");
Type whatIwant = typeof (MyClass<>).MakeGenericType(acType);
Pero, ¿hay una forma más limpia de obtener el tipo final sin analizar, etc.?
fuente
Mira
Activator.CreateInstance
, puedes llamarlo con un tipoActivator.CreateInstance(typeof(MyType))
o con un ensamblado y un nombre de tipo como
string
Activator.CreateInstance("myAssembly", "myType")
Esto le dará una instancia del tipo que necesita.
Si necesitas el
Type
lugar de la instancia, use elType.GetType()
método y el nombre completo del tipo que le interesa, por ejemplo:string s = "System.Text.StringBuilder"; Type myClassType = Type.GetType(s);
Eso te dará la
Type
pregunta en cuestión.fuente
Necesitaba algo como esto y terminé escribiendo un código para analizar los nombres de tipos simples que necesitaba. Por supuesto, hay margen de mejora, ya que no identifica los nombres de tipos genéricos como
List<string>
, pero lo hace muy bien parastring
,int[]
,decimal?
y tal. Compartir en caso de que esto ayude a alguien.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); } }
Usarlo es tan simple como escribir esto:
Type t; t = TypeExtensions.GetTypeFromSimpleName("string"); t = TypeExtensions.GetTypeFromSimpleName("int[]"); t = TypeExtensions.GetTypeFromSimpleName("decimal?");
fuente
Para obtener el objeto de tipo de la cadena, use:
Luego puede pasar esto a
Activator.CreateInstance()
:fuente
No tengo mucho tiempo para analizar esto, aunque creo que he visto algunas respuestas similares. En particular, creo que están haciendo exactamente lo que quieres hacer aquí:
Error de repositorio genérico de Entity Framework
(String.Format("[{0}]", baseType.Name.ToString())).OfType<T>();
Espero que esto ayude, avíseme más específicamente si esto no es así.
fuente