2012-03-06 105 views
3

假设我想编写一个通用的Max方法,该方法返回两个值的最大值。我可以利用通用接口IComparable<T>:[忽略null检查]通用约束语法和用法

static T Max<T>(T x, T z) where T : IComparable<T> 
{ 
    return x.CompareTo(z) > 0 ? x : z; 
} 

细。现在我不明白的第一件事就是以下扩展上面的例子:

static void Initialize<T>(T[] array) where T : new() 
{ 
    for (int i = 0; i < array.length; i++) 
     array[i] = new(T); 
} 

它会在哪里neccessary采用这种语法(new()在这种情况下,这里混淆我)?此外,我已经看到了befuddles我更进一步以下通用模板

class GenericClass<T> where T : SomeClass, Interface 
             where U : new() 
{ /* Some Code */ } 

在这里,我认为T是一种约束是从类型约束U过滤。所以,如果是这样的话,那么我们可以写

class Magic<T> 
{ 
    Magic<U> SomeOtherClass<U>() where U : T { /* Some Code */ } 
} 

做我有这个权利,是多少级这种层次的可能是在C#中?

回答

4

那么,你已经给出了new()约束有用的例子:如果你想用“new”对象填充数组,每个对象都是通过调用无参数构造函数创建的。

至于这样的:

class GenericClass<T> where T : SomeClass, Interface 
            where U : new() 

...这将无法编译,因为它试图约束U,但是这不声明为一个类型参数。

但是你的Magic<T>会编译,并会强制UT适当兼容。 (该确切细节是非常复杂的,请参阅该规范。)

例如,你可以调用

new Magic<Stream>.SomeOtherClass<FileStream>() 

new Magic<IFormattable>.SomeOtherClass<int>() 
+0

你叫我去规范来明天:]。这在这里可能看起来像一个愚蠢的问题,但我想你可以有'Class SuperMagic {SuperMagic Magic(0)}其中U:T {...}我认为这可以永远持续下去吗? 'T'和'U'是唯一可以表示泛型的字母吗?再次感谢您的时间乔恩。祝一切顺利。 – MoonKnight 2012-03-06 23:18:45

+0

@Killercam:说实话,你不太清楚你的例子是什么意思。你应该试试看。不,这里的标识符“U”和“T”是任意的。他们只是名字。如果您真的想要,可以将它们用于类型,并且可以使用任何其他名称作为类型参数。尽管这个约定是以'T'开始的。 – 2012-03-06 23:21:07

+0

@Killercam,这里是获取C#语言规范的链接 - http://msdn.microsoft.com/en-us/library/ms228593(v=vs.100).aspx,特别是第4.4.4节介绍了约束。 – 2012-03-06 23:32:44