簡體   English   中英

使用泛型類型創建類的實例,並在運行時從對象的字符串名稱調用相同泛型類型的方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM