[英]Create instance of class with generic type and call method of same generic type from string name of object at runtime
I have a generic class that has a generic method that uses the same type as the type passed when instantiating the object. 我有一个泛型类,它有一个泛型方法,它使用与实例化对象时传递的类型相同的类型。 At runtime, I will only know the name of the object I need to pass in by a string representation of that object name. 在运行时,我只知道我需要通过该对象名的字符串表示传入的对象的名称。 I've read a few things about using Activator and possibly using dynamic but I can't wrap my head around how I need to make this work. 我已经阅读了一些关于使用Activator和可能使用动态的东西,但我无法理解我需要如何使用它。 Here's a snippet of what my generic class looks like: 这是我的泛型类的样子片段:
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;
}
}
I need to return my IList from the MyMethod() method based on the name of the object I'm passing in as a string. 我需要根据我作为字符串传入的对象的名称从MyMethod()方法返回我的IList。
I could just do a switch/case on the string and then instantiate the MyClass within the case with the reference to the "real" object, but I'm wondering if there's a better (shorter and cleaner) way of doing this. 我可以在字符串上执行切换/大小写,然后使用对“真实”对象的引用来实例化案例中的MyClass,但我想知道是否有更好(更短和更清洁)的方法。
TIA TIA
Your wrapper got the following signature: 您的包装器获得以下签名:
public class MyClass<T> where T : class, new()
it basically says "T needs to be a class and have a default constructor" . 它基本上说“T需要是一个类,并有一个默认的构造函数” 。 The interesting part is about the default constructor. 有趣的部分是关于默认构造函数。 It means that the class must have a constructor with no arguments. 这意味着该类必须具有不带参数的构造函数。
It tells .NET that you can invoke: 它告诉.NET您可以调用:
var obj = new T();
So the first step is to do just that: 所以第一步就是这样做:
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;
}
}
next you wanted to invoke a method. 接下来你想调用一个方法。 That's done with the help of reflection . 这是在反思的帮助下完成的。
A simple example is: 一个简单的例子是:
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"});
Update 更新
I missed the important part: 我错过了重要的部分:
I need to return my IList from the MyMethod() method based on the name of the object I'm passing in as a string. 我需要根据我作为字符串传入的对象的名称从MyMethod()方法返回我的IList。
If the type is declared in the same assembly as your executing code you can just pass the full type name like Some.Namespace.ClassName" to
Type.GetType()`: 如果类型在与执行代码相同的程序集中声明,则可以将完整类型名称(例如Some.Namespace.ClassName" to
Type.GetType()`:
var type = Type.GetType("Some.Namespace.ClassName");
var obj = Activator.CreateInstance(type);
If the class is declared in another assembly you need to specify it: 如果在另一个程序集中声明该类,则需要指定它:
var type = Type.GetType("Some.Namespace.ClassName, SomeAsseblyName");
var obj = Activator.CreateInstance(type);
The rest is pretty much the same. 其余几乎是一样的。
If you only have the class name you can traverse the assembly to find the correct type: 如果只有类名,则可以遍历程序集以查找正确的类型:
var type = Assembly.GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(x => x.Name == "YourName");
var obj = Activator.CreateInstance(type);
It sounds like you want to create the generic type so that you can create an instance of it. 听起来您想要创建泛型类型,以便您可以创建它的实例。
//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);
This assumes that you already know what the generic type is, but not the type argument for that generic type. 这假定您已经知道了泛型类型是什么,但不是为泛型类型的类型参数。 In other words, you're trying to determine what the <T>
is. 换句话说,您正在尝试确定<T>
是什么。
Use Reflection. 使用反射。 Make MyMethod
static. 让MyMethod
静态。 See the code below: 请参阅以下代码:
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.