任何人都可以阐明为什么逆变不适用于C#值类型?
以下不起作用
private delegate Asset AssetDelegate(int m);
internal string DoMe()
{
AssetDelegate aw = new AssetDelegate(DelegateMethod);
aw(32);
return "Class1";
}
private static House DelegateMethod(object m)
{
return null;
}
答案 0 :(得分:5)
问题是 int不是对象。
int可以装箱到一个对象。结果对象(也称为boxed int)当然是一个对象,但它不再是一个整数。
请注意,我在上面使用的“ ”与C#运算符is不同。我的“ ”表示“可通过隐式参考转化转换为”。当我们谈论协方差和逆变时,这就是“是”的含义。
int可隐式转换为对象,但这不是引用转换。它必须装箱。
House
可通过引用转化隐式转换为Asset
。无需创建或修改任何对象。
考虑以下示例。变量house
和asset
都引用了同一个对象。另一方面,变量integer
和boxedInt
具有相同的值,但它们引用了不同的东西。
House house = new House();
Asset asset = house;
int integer = 42;
object boxedInt = integer;
Boxing and Unboxing并不像看起来那么简单。它有许多细微之处,可能会以意想不到的方式影响您的代码。混合拳击与协方差和逆变是一种让任何人炫目的简单方法。
答案 1 :(得分:1)
我同意Anthony Pegram的评论 - 它基于具有与值类型不同的内存占用的引用类型:CLR可以隐式地使用一种类型的类作为其超类型的类,但是当您开始使用值时类型,CLR将需要打包整数,以便它可以在对象的位置工作。
如果你想让它继续工作,我倾向于将声明包装在一个表达式中:
AssetDelegate aw = new AssetDelegate((m) => DelegateMethod(m));
就语法而言,我不知道这是不是很好,但请记住装箱和拆箱是很昂贵的。