2010-12-11 64 views
3

我使用了這種方法的框架使用通用方法,而不是方法的參數

public static void Initialize<T>() where T : Game; 

和示例代碼,你intialize你這樣的比賽

TargetDevice.Initialize<MyGame>(); 

我想知道什麼是好處使用初始化的風格

public static void Initialize<T>() where T : Game; 
TargetDevice.Initialize<MyGame>(); 

,而不是

public static void Initialize(Game game); 
TargetDevice.Initialize(new MyGame()); 

初始化方法的泛型是否有我可以讀取的任何名稱?爲什麼我應該選擇一種而不是另一種?

謝謝。

+4

由於您不需要將'Game'傳遞給第一種方法,因此第二種方法需要它,這似乎很奇怪。 'Type'在這裏就足夠了嗎? – 2010-12-11 11:52:54

+0

很明顯,在兩種方法中,MyGame實例都是由TargetDevice初始化的。使用泛型方法的一個可能的好處是用戶不會參考MyGame的實際實例。這可能是這種類型的泛型編程隱藏實際實例的想法嗎? – Emil 2010-12-11 12:04:26

+0

但有/無*實例*與泛型無關;你可以擁有帶/不帶實例的通用版本,帶/不帶實例的非通用版本。這就是爲什麼我討論了傳遞'Type'與通用'T'的區別。 – 2010-12-11 12:15:50

回答

5

如果你指的區別:

Foo<T>() 

Foo(Type type) 

再就是兩者的優點。後者在使用反射來加載類型時更加方便(也許您的Game類型來自插件?) - 泛型和反射不能很方便地混合使用。

通用版本在編譯時知道所有內容時非常方便;你可以通過約束等來增加額外的驗證,這是由編譯器強制執行的。如果您特別想要使用T,例如通過Comparer<T>.DefaultEqualityComparer<T>.Default(強調:這些僅僅是示例)來使用泛型比較,它可以很方便 - 它可以訪問許多常見模式,同時避免在適當情況下進行裝箱等操作。

在你的情況,因爲T : Game,拳擊不是一個問題(我假設Game是一個類,而不是一個接口)。你可以去任何一個方面;一個List<Game>將工作幾乎以及略微更具體List<T>(其中T : Game),所以這是不太可能導致問題。

如果反射涉及所有,我會使用第二種形式,或許同時提供:

void Foo<T>() where T : Game 
{ 
    Foo(typeof(T)); 
} 
void Foo(Type type) {...} 

最通用的功能,可以模擬 - 例如Activator.CreateInstance(type)代替new T() - 或強制轉換爲已知接口代替T : ISomeInterface。你沒有得到「受限制」操作碼的使用,但是在你的情況下,這並不適用。

相關問題