为什么我不能将Action <int32>转换为Action <object>?</object> </int32>

时间:2013-07-12 14:22:23

标签: c# casting

我有几个地方,我使用了Action<Int32>Action<Boolean>Action<SomeClassName>,但是当在行方法中将操作作为参数传递时,我无法转换{ {1}}或Action<Int32>Action<Boolean>

为什么不能使用简单的类型转换来完成转换?这个演员阵容是否可行?最后,如果有可能,我将如何进行演员表。

3 个答案:

答案 0 :(得分:10)

因为它会打破类型安全。

当您声明Action<Int32>时,您说&#34;这是一个需要一个Int32参数的代理&#34;。

如果可以直接转换为Action<object>,那么您现在可以使用绝对不是Int32的内容调用该操作,例如DateTime。在这种情况下,C#会阻止你在脚下射击。

答案 1 :(得分:3)

你不能通过协方差直接投射(或者它是否是逆转?)因为Action<int>基本上Action<object> - 后者可以传递< em>任何对象,而前者只能 传递int

可以通过包装你的行动来解决这个问题,例如:

Action<int> aInt = ...;
Action<object> aObj = o => aInt((int)o);

这再次向您展示了为什么演员阵容可能不是一个好主意 - 如果您传递aObj除了int之外的任何内容,您将获得演员例外。

相反,理论上你可以只是将Action<object>转换为Action<int>,因为如果你可以传递任何对象,你可以当然传递int。但是,在实践中,这仅适用于参考类型,而不适用于值类型 - 因此您可以使用string,但不能使用int

答案 2 :(得分:1)

动作在其输入为Int32的限制下工作。这意味着您使用的操作可以假设输入为int。例如,您可以使用另一个int n => Console.WriteLine(n + 4)进行数学运算。所以这个动作或功能很适合那个盒子。如果您更改框,则先前做出的假设仍然必须保留。您基本上与“常规”投射场景存在反向关系或逆向,例如:object a = (object) 2;

请记住,任何适合Action框的内容都不得对其输入行为做出任何假设。函数n => Console.WriteLine(n)紧贴内部,因为可以打印所有对象。并非所有对象都可以像int一样。