当前位置: 首页 > 面试题库 >

Java的使用站点差异与C#的声明站点差异相比如何?

锺离高丽
2023-03-14
问题内容

我的理解是,在C#中为泛型指定差异是在类型声明级别进行的:创建泛型类型时,请为类型参数指定差异。另一方面,在Java中,在使用泛型的地方指定了方差:当创建某个泛型类型的变量时,可以指定其类型参数如何变化。

每个选项的优缺点是什么?


问题答案:

我只想回答声明站点和使用站点之间的差异,因为尽管C#和Java泛型在许多其他方面有所不同,但这些差异大多与方差正交。

首先,如果我没记错的话,使用场所方差严格比声明场所方差(尽管以简洁为代价)更强大,或者至少Java的通配符(实际上比使用场所方差更强大)。这种增强的功能对于大量使用状态构造的语言(例如C#和Java)特别有用(但Scala则少得多,特别是因为其标准列表是不可变的)。考虑List<E>(或IList<E>)。由于它具有添加E和获取E的方法,因此它相对于E是不变的,因此无法使用声明位置的方差。但是,对于使用场所方差,您只能说List<+Number>获得的协变子集ListList<-Number>以获得的协变子集。List。在声明站点语言中,库的设计者必须为每个子集创建单独的接口(或类,如果允许类的多重继承),并List扩展这些接口。如果库设计人员不执行此操作(请注意,C#IEnumerable仅处理的协变部分的一小部分IList),那么您就不走运了,并且不得不诉诸于使用某种语言时遇到的相同麻烦差异。

因此,这就是使用站点继承相对于声明站点继承的优势。对于用户而言,声明站点继承相对于使用站点继承的优势基本上是简洁的(前提是设计人员已努力将每个类/接口分为其协变和反协变量部分)。对于类似IEnumerable或的东西Iterator,最好不必每次使用该接口时都指定协方差。Java通过使用冗长的语法(特别是Java的解决方案最理想的双变量)使这一点特别烦人。

当然,这两种语言功能可以共存。对于自然协变或相反的类型参数(例如IEnumerable/
Iterator),请在声明中声明。对于自然不变的类型参数(例如中的in
(I)List),请在每次使用时声明要使用哪种类型的变数。只是不要为带有声明位置差异的参数指定使用位置差异,因为这会使事情变得混乱。

我还没有涉及其他更详细的问题(例如,通配符实际上比使用站点差异更强大),但是我希望这可以回答您对内容的问题。我承认我偏向使用场所差异,但是我试图描绘在与程序员和语言研究人员的讨论中都体现出的两者的主要优势。



 类似资料:
  • 那么在上述任何一个声明中, 为什么和不引用同一个对象?

  • 我在读关于CRCs,我偶然发现了CRC目录和这篇关于CRC-CCITT的文章。 我基于第二个链接实现了(参见下面的代码)。 我是不是遗漏了异或运算的一些属性?在我看来,这两个算法应该有相同的输出(当然不考虑第一个算法的增强),但它们没有。 PS:可执行代码:http://ideone.com/mkuqqq

  • 本文向大家介绍C++与C的差异分析,包括了C++与C的差异分析的使用技巧和注意事项,需要的朋友参考一下 虽说C++是向后兼容C的,但C++与C还是存在许多差异。本文列举了几个例子加以说明,同时这些也是我们非常容易忽略的地方。本文仅简单的列举几例,更多的不同之处读者还需要在学习与实践中不断的进行发掘和总结。 C编译通过但C++编译不通过: 1、C++中编译器不允许在一个函数声明之前调用它,但C中编译

  • 在系统中。识别模型。声明有三个条目:UPN、Name和Name标识符http://schemas.xmlsoap.org/ws/2005/05/identity/claims/namehttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/upnhttp://schemas.xmlsoap.org/ws/2005/05/identity/clai

  • 我很好奇,在声明ArrayList时,这样做有什么区别: 这是: i、 e.未声明<代码>