2011-05-25 192 views
2

我有以下类:类型不可知类在泛类中调用泛型和非泛型方法?

public class GenericClass<T> : IGenericClass<T> where T : class 
{ 
    public GenericClass() 

    public GenericClass(Entity e) 

    public IQueryable<T> GenericMethod1() 

    public IEnumerable<T> GenericMethod2() 

    public T NonGenericMethod1(T t) 
} 

类的伟大工程;但是我开始遇到的问题是,我必须为每个我想要使用的类型实例化GenericClass的另一个实例,并且它变得有点疯狂。我可以创建一些抽象来简化它吗?

我正朝着这个方向前进,但我不知道这是否是正确的选择,或者是否有更好的设计模式可供使用;另外,这两个调用调用根本无法正确工作。

public class TestClass 
{ 
    private Type type; 

    public object Invoke(string method, object obj) 
    { 
     type = obj.GetType(); 

     MethodInfo m = typeof(GenericClass<>).GetMethod(method); 

     var result = new object(); 

     if(m.IsGenericMethod == true) 
      result = m.MakeGenericMethod(type).Invoke(null, new object[] { obj }); 
     else 
      result = m.Invoke(null, new object[] { obj }); 

     return result; 
    } 
} 

TIA

+3

对你来说可能很明显,但对我来说完全不清楚:你在做什么? – dtb 2011-05-25 23:23:14

+0

对象是否是GenericClass 或T的实例? – dlev 2011-05-25 23:23:30

+0

@dlev - obj是一个T. @dtb的实例 - 我想要一个可以实例化一次的类,然后调用GenericClass中的任何方法,通过传递它来设置类型,而不必为每个我需要的类型实例化一个GenericClass的不同实例。我不确定是否有可能,但是如果我现在可以在我的代码库中,那肯定会让我的生活更轻松...... – morganpdx 2011-05-25 23:31:48

回答

2

但是我已经开始运行到哪里我必须实例GenericClass的另一个实例为每一种类型的TI希望使用的问题,它变得有点疯狂

很难没有一些猜测GenericClass的实现......但我看到构造函数和方法 - 没有属性(也没有字段?)。

如果是这种情况,您可能希望使用静态方法使GenericClass成为静态类。然后,你不准实例化它,你可以从类型直接调用方法:

public static class GenericClass 
{ 
    public static IQueryable<T> GenericMethod1<T>() where T:class 

    public static IEnumerable<T> GenericMethod2<T>() where T:class 

    public static object NonGenericMethod1(object t) 
} 

调用由

IQueryable<Customer> query = GenericClass.GenericMethod1<Customer>(); 
IEnumerable<Customer> items = GenericClass.GenericMethod2<Customer>(); 
Customer c = (Customer) GenericClass.NonGenericMethod1(customerInstance); 

或许有属性或字段,但他们AREN不依赖于T,那么你可以将Generic责任移到方法而不是类上。

现在你可以拥有一个实例,并且该实例可以处理你想要抛出的所有T。

public class GenericClass : IGenericClass 
{ 
    public IQueryable<T> GenericMethod1<T>() where T:class 

    public IEnumerable<T> GenericMethod2<T>() where T:class 

    public object NonGenericMethod1(object t) 
} 

我对这个答案的通用岬道歉,但是这是由于问题的一般性的烦躁。

+0

我喜欢把方法而不是类的通用责任移动...我认为这将工作。我会试一试......谢谢! – morganpdx 2011-05-25 23:51:31

1

我不认为这种做法会工作。主要问题是您正尝试根据类型创建泛型方法,以避免实例化相应的GenericClass<T>的实例。但是你的Invoke s失败的原因是你传递了null作为目标对象,即使它们是实例方法。让他们工作的方法是构建适当的GenericClass<T>的实例,但当然这是你想要避免的。

如果你想去这个反光标识的路线(所以你仍然有集中建设的位置),你可以通过反射用下面的代码做到这一点:

Type specificType = typeof(GenericClass<>).MakeGenericType(new Type[] { type }); 
var specificInstance = Activator.CreateInstance(specificType); 

然后,您可以在specificInstance作为传递第一个参数为Invoke()

+0

谢谢@dlev!我要给大卫B的答案一个镜头,但如果它不起作用,我会接下来尝试。谢谢! – morganpdx 2011-05-25 23:52:16