2009-10-07 39 views
2

當我只有一個通用參數時,有什麼方法可以在類型上調用靜態成員。例如,如果我有這樣的事情當你只有通用參數時調用靜態成員

public Get<T>(int id) 
{ 
    // I would like to do this 
    string s = T.SomeMethodName(); 
} 

我能做到這樣,但有點「難吃」,然後,如果它是靜態的還是沒有也沒關係。或者我可以使用Yuriy建議的反射。

ISomeKnownInterface i = (ISomeKnownInterface) new T(); 
string s = i.SomeMethodName(); 

所以,問題是現在是更好的方法,使用反射

public TFormDto Get<TFormDto>(int entityId) where TFormDto : AbstractEntityFormDto, new() 
     { 
// create new instance 
      AbstractEntityFormDto a = (AbstractEntityFormDto) new TFormDto(); 
      string entityName = a.GetEntityFullTypeName(); 

// use reflection 

      Type type = typeof(TFormDto); 
      string entityName = type.GetMethods(BindingFlags.Public | BindingFlags.Static) 
       .Single(m => m.Name == "GetEntityFullTypeName") 
       .Invoke(null, null); 

回答

1

的創建新實例,那不是應該始終AbstractBaseClass.GetFullName()。否則,你必須使用T上的反射來獲得另一個類的靜態方法。 This可能會對您有所幫助。

下面是一個簡單的例子:

class TestClass 
{ 
    public static void Hello() 
    { 

     Console.WriteLine("World!!!"); 
    } 
} 

public static void Test<T>() where T : class 
{ 
    Type type = typeof(T); 
    type.GetMethods(BindingFlags.Public | BindingFlags.Static) 
     .Single(m => m.Name == "Hello") 
     .Invoke(null, null); 

}  

與樣品,我假設你知道接口沒有靜態方法。我假設你的意思是你有一個接口,它有一個靜態方法的簽名,一個實現上述接口的類只是從實現中調用靜態方法。這也可以,但不能保證正確的靜態會被調用,並確保T對該接口有一個約束,而不僅僅是new()。

+0

是的,它會的。我試圖定義抽象靜態,這是不允許的。 – epitka

+0

通過像這樣的反射來調用方法會更快,然後就像這樣做。這是不是很新鮮,但這是這個框架代碼 AbstractEntityFormDto v =(AbstractEntityFormDto)new TFormDto(); string s = v.EntityFullTypeName; – epitka

+0

你能編輯你的問題嗎,我對你剛剛用這種格式寫的內容感到困惑。 –

1

問題是不能保證T有一個名爲SomeMethodName的靜態成員方法。如果你打算撥打AbstractBaseClass.SomeMethodName,那就這樣做。爲什麼這是不可能的理由是static interface methods討論的延伸。

+0

爲了不好,我們沒有通用參數方法的約束。這將解決我的問題。 – epitka

0

沒有使用反射,沒有辦法做到這一點。要調用一個靜態方法,你總是需要指定實際的類型。

如果你想提高你的代碼的編譯時安全性,你會盡量避免反射。使該方法非靜態並將其放入界面中。這將最有可能(我不知道你的問題)是最乾淨的解決方案。

爲了受益於接口和多態性,我讓很多成員非靜態的。有時我實現類似於單例模式的東西(例如,獲取實例的靜態屬性),或者只是調用默認構造函數來獲取實例並將其作爲參數傳遞。

interface ISomeInterface 
{ 
    string SomeMethodName(); 
} 

class SomeImplementation : ISomeInterface 
{ 
    public static Instance { get { return new SomeImplementation(); } } 

    public string SomeMethodName() 
    { 
    // implementation of SomeMethodName 
    } 
} 

public Get(ISomeInterface i) 
{ 
    string s = i.SomeMethodName(); 
} 

public Example() 
{ 
    Get(SomeImplementation.Instance); 
} 

您也可以建立在通用方法的新實例,你還可以指定你需要一個默認的構造函數:

public Get<T>() where T : ISomeInterface, new() 
{ 
    T instance = new T(); 
    string s = instance.SomeMethodName(); 
} 

public Example() 
{ 
    Get<SomeImplementation>(); 
} 
+0

問題是我沒有一個實例只是一個泛型參數。所以基本上我的選擇是新增實例並獲取值或使用反射。 – epitka

+0

你不能用通用參數改變你的方法的接口嗎? –

+0

在這種情況下,我不能更改方法簽名,它必須具有通用參數。 – epitka

相關問題