.NET中struct和class之间有什么区别?
IEnumerable<T>是共变体,但它不支持值类型,仅支持引用类型.以下简单代码编译成功:
IEnumerable<string> strList = new List<string>();
IEnumerable<object> objList = strList;
Run Code Online (Sandbox Code Playgroud)
但是从更改string到int将得到编译错误:
IEnumerable<int> intList = new List<int>();
IEnumerable<object> objList = intList;
Run Code Online (Sandbox Code Playgroud)
原因在MSDN中解释:
差异仅适用于参考类型; 如果为变量类型参数指定值类型,则该类型参数对于生成的构造类型是不变的.
我搜索过并发现有些问题提到的原因是值类型和引用类型之间的装箱.但它仍然不清楚我的想法为什么拳击是什么原因?
有人可以给出一个简单而详细的解释为什么协方差和逆变不支持值类型以及拳击如何影响这个?
在下面的代码我希望能够隐式地从投elements至baseElements因为TBase可以隐式转换IBase.
public interface IBase { }
public interface IDerived : IBase { }
public class VarianceBug
{
public void Foo<TBase>() where TBase : IBase
{
IEnumerable<TBase> elements = null;
IEnumerable<IDerived> derivedElements = null;
IEnumerable<IBase> baseElements;
// works fine
baseElements = derivedElements;
// error CS0266: Cannot implicitly convert type
// 'System.Collections.Generic.IEnumerable<TBase>' to
// 'System.Collections.Generic.IEnumerable<IBase>'.
// An explicit conversion exists (are you missing a cast?)
baseElements = elements;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到了评论中提到的错误.
引用规范:
A型
T<A1, …
为什么不允许最后一行?
IEnumerable<double> doubleenumerable = new List<double> { 1, 2 };
IEnumerable<string> stringenumerable = new List<string> { "a", "b" };
IEnumerable<object> objects1 = stringenumerable; // OK
IEnumerable<object> objects2 = doubleenumerable; // Not allowed
Run Code Online (Sandbox Code Playgroud)
这是因为double是一个不是从对象派生的值类型,因此协方差不起作用?
这是否意味着没有办法让这项工作:
public interface IMyInterface<out T>
{
string Method();
}
public class MyClass<U> : IMyInterface<U>
{
public string Method()
{
return "test";
}
}
public class Test
{
public static object test2()
{
IMyInterface<double> a = new MyClass<double>();
IMyInterface<object> b = a; // Invalid cast!
return b.Method();
} …Run Code Online (Sandbox Code Playgroud)