对于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的接口然后使用它。因此,每当我想编写一些泛型类时,我必须编写一个单独的接口来支持所有派生类的所有协变操作,并确保我的类实现该接口?这是正确的还是我错过了什么。
由于
答案 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>();
}