with method getfields español c# reflection types

method - reflection c# español



¿Cómo puedo obtener un tipo genérico a partir de una representación de cadena? (5)

Tengo MyClass<T> .

Y luego tengo esta string s = "MyClass<AnotherClass>"; . ¿Cómo puedo obtener Tipo de la cadena s ?

Una forma (fea) es analizar el "<" y ">" y hacer:

Type acType = Type.GetType("AnotherClass"); Type whatIwant = typeof (MyClass<>).MakeGenericType(acType);

Pero, ¿hay una manera más clara de obtener el tipo final sin ningún análisis sintáctico, etc.?


Echa un vistazo a Activator.CreateInstance : puedes llamarlo con un tipo

Activator.CreateInstance(typeof(MyType))

o con un ensamblaje y nombre de tipo como string

Activator.CreateInstance("myAssembly", "myType")

Esto le dará una instancia del tipo que necesita.

Si necesita el Type lugar de la instancia, use el método Type.GetType() y el nombre completo del tipo que le interesa, por ejemplo:

string s = "System.Text.StringBuilder"; Type myClassType = Type.GetType(s);

Eso te dará el Type en cuestión.


El formato para genéricos es el nombre, un carácter `, el número de parámetros de tipo, seguido de una lista delimitada por comas de los tipos entre paréntesis:

Type.GetType("System.Collections.Generic.IEnumerable`1[System.String]");

No estoy seguro de que haya una manera fácil de convertir la sintaxis de C # para los genéricos al tipo de cadena que quiere el CLR. Empecé a escribir una expresión regular rápida para analizarla como mencionaste en la pregunta, pero me di cuenta de que a menos que abandones la capacidad de tener genéricos anidados como parámetros de tipo, el análisis se volverá muy complicado.


He necesitado algo así y terminé escribiendo un código para analizar los nombres de tipos simples que necesitaba. Por supuesto, hay margen de mejora, ya que no identificará los nombres de tipos genéricos como List<string> , pero sí se aplica a string , 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?");


No tengo mucho tiempo para analizar todo 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, hágamelo saber más específicamente si esto no es así.


Para obtener el objeto tipo de la cadena, use:

Type mytype = Type.GetType(typeName);

A continuación, puede pasar esto a Activator.CreateInstance() :

Activator.CreateInstance(mytype);