2010-12-11 38 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。你没有得到“受限制”操作码的使用,但是在你的情况下,这并不适用。

相关问题