我有几个地方我都使用Action<Int32>
,Action<Boolean>
,Action<SomeClassName>
,但是当涉及到传递行动的一类方法的参数,我不能投Action<Int32>
或Action<Boolean>
到Action<Object>
。为什么我不能动作<Int32>动作<Object>?
为什么不能用简单的类型转换进行转换?这个演员是可能的吗?最后,如果可能的话,我将如何去做这个演员阵容。
我有几个地方我都使用Action<Int32>
,Action<Boolean>
,Action<SomeClassName>
,但是当涉及到传递行动的一类方法的参数,我不能投Action<Int32>
或Action<Boolean>
到Action<Object>
。为什么我不能动作<Int32>动作<Object>?
为什么不能用简单的类型转换进行转换?这个演员是可能的吗?最后,如果可能的话,我将如何去做这个演员阵容。
因为它会破坏类型安全。
当您声明Action<Int32>
时,您说“这是需要一个Int32参数的代表”。
如果这可以直接转换为Action<object>
,那么您现在可以使用肯定不是Int32
的行为来调用动作,例如DateTime
。在这种情况下,C#可以防止你在脚下拍摄自己。
你不能让经协方差直接投(或者是逆变?),因为Action<int>
根本不一个Action<object>
- 后者可以传递任何对象,而前者可以只是通过了int
。
您可以围绕此包裹你的动作,这样的:
Action<int> aInt = ...;
Action<object> aObj = o => aInt((int)o);
这再次表明你为什么投可能不是一个好主意 - 如果你通过aObj
任何东西,除了一个int
,你会得到一个演员例外。
相反,你可以在理论上只投一个Action<object>
到Action<int>
,因为如果你可以通过它任何对象,可以肯定通它的int
。但是,实际上这只适用于参考类型,而不适用于值类型 - 因此您可以使用string
,但不适用于int
。
在输入为Int32的限制下进行操作。这意味着您使用的操作可以对输入作为int进行假设。例如,你可以用另一个int n => Console.WriteLine(n + 4)
做数学运算。所以这个动作或功能很适合那个盒子。如果你改变方框,以前做出的假设仍然必须保持。你基本上有一个反向关系,或逆变,到“常规”铸造方案,例如:object a = (object) 2;
。
只要记住任何符合操作框的东西都不会对其输入行为做任何假设。功能n => Console.WriteLine(n)
紧贴在里面,因为所有的对象都可以被打印。并非所有对象都可以像整数一样操作。
这将是协变性,但'行动'在T中是逆变的。它是协变性,如果“可转换性箭头”朝相同的方向。如果'string - > object'暗示'X - > X
...就这样,'co'和'contra'现在对我有意义。谢谢埃里克! – Rawling