Ray*_*ess 3 c# generics reflection typeof gettype
我最近有这个问题.
doSomething(typeof(int));
doSomething(typeof(MyClassA));
doSomething(typeof(MyClassB));
public void doSomething(Type _type)
{
var myGenObj = new MyGenericClass<_type>(); // Error. Really I'd want MyGenericClass<int>, MyGenericClass<MyClassA>, etc depending on what's passed in.
myGenObj.doSomeGenStuff();
// more stuff...
}
Run Code Online (Sandbox Code Playgroud)
我认为这可以通过某种方式进行反思.可能有一种更简单的方法.关于Type的工作方式和类下的Classes,我有点困惑.无论如何,谢谢你的帮助.
谢谢.
你想要Type.MakeGenericType然后Activator.CreateInstance......但是然后在新创建的对象上调用方法将是棘手的.理想情况下,您可以拥有包含这些成员的非泛型基类或接口:
public interface IFoo
{
void CallSomeMethod();
}
public class MyGenericClass<T> : IFoo
{
...
}
// Names changed to be more conventional
public void DoSomething(Type type)
{
var genericType = typeof(MyGenericClass<>).MakeGenericType(type);
var instance = (IFoo) Activator.CreateInstance(genericType);
instance.CallSomeMethod();
}
Run Code Online (Sandbox Code Playgroud)
如果确实需要调用依赖于类型参数的方法,则需要使用反射来实现,或者使用dynamic反射来简化基于反射的代码.
编辑:正如cdhowie所说,如果你总是在编译时确实知道类型,你可以使用一个通用的方法,这将使事情变得更简单.然后你会调用这样的方法:
DoSomething<int>();
DoSomething<MyClassA>();
DoSomething<MyClassB>();
Run Code Online (Sandbox Code Playgroud)
像这样:
object myGenObj = Activator.CreateInstance(typeof(MyGenericClass<>).MakeGenericType(_type));
Run Code Online (Sandbox Code Playgroud)
但是,由于生成的对象属于您在编译时不知道的类型,因此您无法真正通过泛型类型调用对象的成员(通过反射除外)。如果您在编译时确实知道某个祖先类型或已实现的接口,则可以强制转换为该类型,然后调用该成员。
您还可以考虑将这个功能包装在一个通用方法中,这使得整个事情更容易处理:
public void doSomething<T>()
{
var myGenObj = new MyGenericClass<T>();
myGenObj.doSomeGenStuff();
}
Run Code Online (Sandbox Code Playgroud)
如果您必须支持Type对象,您可以使用使用反射作弊的重载:
public void doSomething(Type _type)
{
this.GetType().GetMethod("doSomething", Type.EmptyTypes)
.MakeGenericMethod(_type)
.Invoke(this, null);
}
Run Code Online (Sandbox Code Playgroud)