如果编译器可以推断它,C#不要求您指定泛型类型参数,例如:
ListmyInts = new List {0,1,1, 2,3,5,8,13,21,34,55,89,144,233,377, 610,987,1597,2584,4181,6765}; //this statement is clunky List myStrings = myInts. Select ( i => i.ToString() ). ToList (); //the type is inferred from the lambda expression //the compiler knows that it's taking an int and //returning a string List myStrings = myInts. Select( i => i.ToString() ). ToList();
这是匿名类型所必需的,你不知道类型参数是什么(在intellisense中它显示为'a
),因为它是由编译器添加的.
类级别类型参数不允许您这样做:
//sample generic class public class GenericDemo{ public GenericDemo ( T value ) { GenericTypedProperty = value; } public T GenericTypedProperty {get; set;} } //why can't I do: int anIntValue = 4181; var item = new GenericDemo( anIntValue ); //type inference fails //however I can create a wrapper like this: public static GenericDemo Create ( T value ) { return new GenericDemo ( value ); } //then this works - type inference on the method compiles var item = Create( anIntValue );
为什么C#不支持这个类级泛型类型推断?
实际上,你的问题还不错.在过去的几年里,我一直在玩一种通用的编程语言,尽管我从来没有真正开发它(也许永远不会),我已经考虑了很多关于泛型类推理的问题,而且我的首要任务之一是总是允许构造类而不必指定泛型类型.
C#只是缺乏一套规则来实现这一目标.我认为开发人员从来没有看到包含这个的必要性.实际上,以下代码将非常接近您的命题并解决问题.所有C#需求都是一个额外的语法支持.
class Foo{ public Foo(T x) { … } } // Notice: non-generic class overload. Possible in C#! class Foo { public static Foo ctor (T x) { return new Foo (x); } } var x = Foo.ctor(42);
由于这段代码确实有效,我们已经证明问题不是语义问题,而只是缺乏支持问题.我想我必须收回以前的帖子.;-)
为什么C#不支持这个类级泛型类型推断?
因为它们通常含糊不清.相比之下,类型推断对于函数调用来说是微不足道的(如果所有类型都出现在参数中).但是在构造函数调用(美化函数,为了讨论)的情况下,编译器必须同时解析多个级别.一个级别是类级别,另一个级别是构造函数参数级别.我相信解决这个问题在算法上是非平凡的.直观地说,我认为它甚至是NP完全的.
为了说明无法解决分辨率的极端情况,请想象下面的类并告诉我编译器应该做什么:
class Foo{ public Foo(U x) { } } var x = new Foo(1);