当有明确的引用类型时,Java可以推断出通用类型参数。例如,这两种情况都可以。
Set<String> set = new HashSet<string>();
Set<String> set2 = new HashSet<>();
不幸的是,如果我尝试在C#中做类似的事情,它似乎不被支持。
//Doesn't compile
ISet<string> set = new HashSet<>();
//Works OK
ISet<string> set2 = new HashSet<string>();
在C#中,我收到了两条来自上述的编译器消息。
CS7003 意外地使用一个未绑定的通用名。
和
CS0266 不能隐式地将类型'System.Collections.Generic.HashSet'转换为'System.Collections.Generic.ISet'。显式转换是存在的(你是否缺少一个转换?)
这个功能是真的不支持还是我漏掉了一些C#语法?
感谢以下人士的评论 canton7 我们有一个答案。这个功能还没有被C#支持,但在管道中围绕这个问题进行了讨论。有两个可能的方向可以采取。
有一种建议是使用钻石操作符,就像问题中所说的那样。
https:/github.comdotnetcsharplangissues2935。
这将允许我们使用类似于上述的Java语法,其中引用类型是一个接口,对象类型是该接口的一些实现。
有建议说,使用 new
关键字。
https:/github.comdotnetcsharplangissues100。
例如,这项建议将允许以下内容。
Point p = new Point(1, 2);
简单地替换为:
Point p = new (1, 2);
事实上,对于通用类型来说,类型和任何与之相关的通用类型,都会被推断出来。因此,我们可以这样做,例如。
Hashset<string> set = new();
这最初看起来比钻石运算符的建议更强大。然而,回到问题中最初的例子,这个功能如果被开发出来,将不适用于引用类型是接口的情况。在这种情况下,我们将不清楚该从哪个对象创建 new
. 比如说如果我们这样做了。
ISet<string> set = new ();
那编译器怎么知道是哪个实现的?ISet
接口来实例化该类型的对象?所以即使实现了这个功能,也不能解决引用类型是接口的用例。