2011-05-25 194 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