有界类型变量Java vs C#

时间:2013-10-19 10:28:31

标签: c# java .net generics

对于Java中的以下代码,c#中是否存在等价物

List<? extends Number> list;
list = new ArrayList<Float>();
list = new ArrayList<Integer>();
list.add(Float.valueOf("4.0")); // doesn't compile and it is fine
Number e = list.get(0); // workds

我正在阅读c#

中的协变类型
List<SomeClass> list2 = new List<SomeClass>();
IEnumerable<Object> list3 = list2; // works

根据我的理解,Java中的所有接口/类默认支持协方差。根据声明中使用的类型参数,不支持不遵循协方差的功能(将参数化类型作为输入的方法)。含义,List<? extends Number> 可以参考List<Integer> or a List<Double>,但它不再支持add()等方法。

现在,在C#的另一端,看起来我需要找到一个支持Covariance的接口然后使用它。因此,每当我想编写一些泛型类时,我必须编写一个单独的接口来支持所有派生类的所有协变操作,并确保我的类实现该接口?这是正确的还是我错过了什么。

由于

1 个答案:

答案 0 :(得分:1)

你的问题,
对于Java中的以下代码,c#中是否存在等价物

    List<? extends Number> list;
    list = new ArrayList<Float>();
    list = new ArrayList<Integer>();
    list.add(Float.valueOf("4.0")); // doesn't compile and it is fine
    Number e = list.get(0); // workds

不,直接没有等价物,因为'Number'没有基类或超类或接口,但有一个等价物(类似于'?'运算符),where关键字。

您可以在msdn page上获取有关它的更多信息。

您可以在内联为类中的变量内联,只需:

public class ArrayList<T> where T: someBaseClass
{
   List<T> list = new List<DerivedTypeOfSomeBaseClass>();
}

或在函数内部

public T getArrayList<T>(ArrayList<T> arr) where T: someBaseClass
List<T> list = new List<DerivedTypeOfSomeBaseClass>()

你的问题

  

现在,在C#的另一端,看起来我需要找到一个支持Covariance的接口然后使用它。因此,每当我想编写一些泛型类时,我必须编写一个单独的接口来支持所有派生类的所有协变操作,并确保我的类实现该接口?这是正确的还是我错过了什么

协方差和逆变的一般概念表明,协方差是使用比泛型参数指定的更多派生类型的能力,而逆变是使用较少派生类型的能力。 有关协方差和逆变的详细说明,请阅读MSDN link 所以,如果你想通过Generic方式做这件事你是对的,你必须有一个支持所有协变操作的公共基本接口。

在您的特定情况下,对于数字,C#中的所有字节,双字符,浮点数,整数,长字符,短字节实现IComparable,IFormattable,IConvertible,IComparable,IEquatable接口,因此对于您的第一个问题,

 public class Program<K> where K : IComparable, IFormattable, IConvertible, IComparable<K>, IEquatable<K>
{
  static void Main()
  {  
        Program<int> pro = new Program<int>();
        Program<Byte> bpro = new Program<Byte>();
        Program<Double> dpro = new Program<Double>();
        Program<Int64> fpro = new Program<Int64>();
        Program<long> lpro = new Program<long>();
        Program<short> spro = new Program<short>();
   }