使用泛型类型创建类的实例,并在运行时从对象的字符串名称调用相同泛型类型的方法

Bla*_*mes 2 c# generics dynamic activator

我有一个泛型类,它有一个泛型方法,它使用与实例化对象时传递的类型相同的类型.在运行时,我只知道我需要通过该对象名的字符串表示传入的对象的名称.我已经阅读了一些关于使用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;
        }
}
Run Code Online (Sandbox Code Playgroud)

我需要根据我作为字符串传入的对象的名称从MyMethod()方法返回我的IList.

我只是做一个开关/箱的字符串,然后与参考"真正的"对象的情况中实例的MyClass的,但我不知道是否有这样做的更好(更短和更清洁的)的方式.

TIA

jga*_*fin 8

您的包装器获得以下签名:

public class MyClass<T> where T : class, new()
Run Code Online (Sandbox Code Playgroud)

它基本上说"T需要是一个类,并有一个默认的构造函数".有趣的部分是关于默认构造函数.这意味着该类必须具有不带参数的构造函数.

它告诉.NET您可以调用:

var obj = new T();
Run Code Online (Sandbox Code Playgroud)

所以第一步就是这样做:

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;
        }
}
Run Code Online (Sandbox Code Playgroud)

接下来你想调用一个方法.这是在反思的帮助下完成的.

一个简单的例子是:

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"});
Run Code Online (Sandbox Code Playgroud)

更新

我错过了重要的部分:

我需要根据我作为字符串传入的对象的名称从MyMethod()方法返回我的IList.

如果类型在与执行代码相同的程序集中声明,则只需传递完整的类型名称,如Some.Namespace.ClassName" toType.GetType()`:

var type = Type.GetType("Some.Namespace.ClassName");
var obj = Activator.CreateInstance(type);
Run Code Online (Sandbox Code Playgroud)

如果在另一个程序集中声明该类,则需要指定它:

var type = Type.GetType("Some.Namespace.ClassName, SomeAsseblyName");
var obj = Activator.CreateInstance(type);
Run Code Online (Sandbox Code Playgroud)

其余几乎是一样的.

如果只有类名,则可以遍历程序集以查找正确的类型:

var type = Assembly.GetExecutingAssembly()
                   .GetTypes()
                   .FirstOrDefault(x => x.Name == "YourName");
var obj = Activator.CreateInstance(type);
Run Code Online (Sandbox Code Playgroud)