虽然只相差一个字,但是区别还是挺大的。
先看看两个词的英文表述:constraints on type parameters和type parameters as constraints
其中后者最准确的翻译应该是“(用)类型参数(作为)约束”,有些人也许会说你一个搞技术的也来这些标题党的名堂,明明这么多字,你非得省几个,搞个危言耸听,这还真不是,具体的慢慢往下看。
这篇博文主要来源于我对为了理解泛型中的where T : U这个东东找了一些资料
对这个内容解释最权威的还是微软的文档,看这里
我写了个简单的例子来验证:
public class Animal { } public class Human : Animal { } public class AnimalList<T> where T : Animal { public void AddT(List<T> items) { } public void AddU<U>(List<U> items) where U : T { } }
调用的代码:
List<Animal> animals = new List<Animal>(); animals.Add(new Human()); animals.Add(new Animal()); List<Human> humen = new List<Human>(); humen.Add(new Human()); //error CS1503: 参数 1: 无法从“ConsoleApp1.Animal”转换为“ConsoleApp1.Human” //humen.Add(new Animal()); var list = new AnimalList<Animal>(); list.AddT(animals); //error CS1503: 参数 1: 无法从“System.Collections.Generic.List<ConsoleApp1.Human>”转换为“System.Collections.Generic.List<ConsoleApp1.Animal>” //list.AddT(humen); list.AddU(humen);
主要的区别就在AddT和AddU两个函数上
where T : U的本质是用泛型参数来约束泛型参数,真绕口啊,其他的约束都是用具体类型来约束,碰到具体类型不好使的时候就要考虑用它了,不过用这种方法也有明显的限制,
因为编译器除了假设类型参数派生自System.Object
以外,不能做出更强的假设,所以如果要在两个类型参数之间强制继承关系,可以将类型参数用作泛型类的约束。
最后再说说标题的事情,类型参数约束这个词不是我取的,是Eric Lippert,如果对这个名字不熟悉,看看他的个人简介吧
Eric Lippert designs programming languages at Facebook. Other notable work includes designing C# analyzers at Coverity, and developing the Visual Basic, VBScript, JScript and C# compilers at Microsoft.
据他说在C#编译器项目组中他们就管这东东叫"type parameter constraints",直译过来不就是“类型参数约束”,^_^
BTW:注意struct是隐式密封的,所以在泛型中涉及到派生什么的时候都是说class(严格点说是引用类型),这点备忘下。