[英]Create instance of class with generic type and call method of same generic type from string name of object at runtime
我有一個泛型類,它有一個泛型方法,它使用與實例化對象時傳遞的類型相同的類型。 在運行時,我只知道我需要通過該對象名的字符串表示傳入的對象的名稱。 我已經閱讀了一些關於使用Activator和可能使用動態的東西,但我無法理解我需要如何使用它。 這是我的泛型類的樣子片段:
public class MyClass<T> where T : class, new()
{
public IList<T> MyMethod(Stream stream)
{
var data = new List<T>();
// stuff to create my list of objects
return data;
}
}
我需要根據我作為字符串傳入的對象的名稱從MyMethod()方法返回我的IList。
我可以在字符串上執行切換/大小寫,然后使用對“真實”對象的引用來實例化案例中的MyClass,但我想知道是否有更好(更短和更清潔)的方法。
TIA
您的包裝器獲得以下簽名:
public class MyClass<T> where T : class, new()
它基本上說“T需要是一個類,並有一個默認的構造函數” 。 有趣的部分是關於默認構造函數。 這意味着該類必須具有不帶參數的構造函數。
它告訴.NET您可以調用:
var obj = new T();
所以第一步就是這樣做:
public class MyClass<T> where T : class, new()
{
public IList<T> MyMethod(Stream stream)
{
var data = new List<T>();
//this
var obj = new T();
return data;
}
}
接下來你想調用一個方法。 這是在反思的幫助下完成的。
一個簡單的例子是:
var obj = new T();
//get type information
var type = obj.GetType();
//find a public method named "DoStuff"
var method = type.GetMethod("DoStuff");
// It got one argument which is a string.
// .. so invoke instance **obj** with a string argument
method.Invoke(obj, new object[]{"a string argument"});
更新
我錯過了重要的部分:
我需要根據我作為字符串傳入的對象的名稱從MyMethod()方法返回我的IList。
如果類型在與執行代碼相同的程序集中聲明,則可以將完整類型名稱(例如Some.Namespace.ClassName" to
Type.GetType()`:
var type = Type.GetType("Some.Namespace.ClassName");
var obj = Activator.CreateInstance(type);
如果在另一個程序集中聲明該類,則需要指定它:
var type = Type.GetType("Some.Namespace.ClassName, SomeAsseblyName");
var obj = Activator.CreateInstance(type);
其余幾乎是一樣的。
如果只有類名,則可以遍歷程序集以查找正確的類型:
var type = Assembly.GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(x => x.Name == "YourName");
var obj = Activator.CreateInstance(type);
聽起來您想要創建泛型類型,以便您可以創建它的實例。
//Assuming "typeName" is a string defining the generic parameter for the
//type you want to create.
var genericTypeArgument = Type.GetType(typeName);
var genericType = typeof (MyGenericType<>).MakeGenericType(genericTypeArgument);
var instance = Activator.CreateInstance(genericType);
這假定您已經知道了泛型類型是什么,但不是為泛型類型的類型參數。 換句話說,您正在嘗試確定<T>
是什么。
使用反射。 讓MyMethod
靜態。 請參閱以下代碼:
public object run(string typename, Stream stream)
{
var ttype = Assembly
.GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(x => x.Name == typename);
MethodInfo minfo = typeof(MyClass)
.GetMethod("MyMethod", BindingFlags.Static | BindingFlags.Public);
return minfo
.MakeGenericMethod(ttype)
.Invoke(null, new object[] { stream });
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.