Mam MyClass<T>
.
A potem mam to string s = "MyClass<AnotherClass>";
. Jak mogę uzyskać Type z ciągu s
?
Jednym ze sposobów (brzydkim) jest przeanalizowanie „<” i „>” i wykonanie:
Type acType = Type.GetType("AnotherClass");
Type whatIwant = typeof (MyClass<>).MakeGenericType(acType);
Ale czy istnieje bardziej przejrzysty sposób uzyskania ostatecznego typu bez analizowania itp.?
źródło
Sprawdź
Activator.CreateInstance
- możesz to nazwać typemActivator.CreateInstance(typeof(MyType))
lub z nazwą zestawu i typu jako
string
Activator.CreateInstance("myAssembly", "myType")
W ten sposób uzyskasz instancję odpowiedniego typu.
Jeśli potrzebujesz
Type
instancji, a nie instancji, użyjType.GetType()
metody i w pełni kwalifikowanej nazwy typu, który Cię interesuje, np .:string s = "System.Text.StringBuilder"; Type myClassType = Type.GetType(s);
To da ci
Type
pytanie.źródło
Potrzebowałem czegoś takiego i skończyło się na napisaniu kodu, aby przeanalizować proste nazwy typów, których potrzebowałem. Oczywiście istnieje możliwość poprawy, gdyż nie będą identyfikować nazwy rodzajowe typu jak
List<string>
, ale robi dobrze dlastring
,int[]
,decimal?
i takie. Udostępnianie na wypadek, gdyby to komuś pomogło.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); } }
Używanie go jest tak proste, jak napisanie tego:
Type t; t = TypeExtensions.GetTypeFromSimpleName("string"); t = TypeExtensions.GetTypeFromSimpleName("int[]"); t = TypeExtensions.GetTypeFromSimpleName("decimal?");
źródło
Aby po prostu pobrać obiekt typu z ciągu, użyj:
Następnie możesz przekazać to
Activator.CreateInstance()
:źródło
Nie mam dużo czasu, aby to przeanalizować, chociaż wydaje mi się, że widziałem kilka podobnych odpowiedzi. W szczególności myślę, że robią dokładnie to, co chcesz tutaj zrobić:
Entity Framework Generic Repository Error
(String.Format("[{0}]", baseType.Name.ToString())).OfType<T>();
Mam nadzieję, że to pomoże. Jeśli tak nie jest, daj mi znać bardziej szczegółowo.
źródło