关于《C# in Depth》中Func协变逆变示例转换方向的疑问
关于《C# in Depth》第四版147页Func协变逆变示例的解答
首先明确Func<in T, out TResult>的核心规则:
- 逆变(
in T参数):允许将接受基类类型参数的委托,转换为接受派生类类型参数的委托(比如Func<object, int>可以赋值给Func<string, int>)——因为派生类实例可以安全传递给基类类型的参数。 - 协变(
out TResult返回值):允许将返回派生类类型的委托,转换为返回基类类型的委托(比如Func<int, string>可以赋值给Func<int, object>)——因为派生类实例可以安全赋值给基类类型的变量。
针对你的疑问:
书中的dynamic到object的转换是完全正确的。原因如下:
dynamic类型在运行时本质就是object,且编译时支持隐式转换为object。- 如果这个转换是针对
TResult(协变方向),那么Func<T, dynamic>转换为Func<T, object>完全符合协变规则:返回dynamic的结果可以安全赋值给object类型,这和第一个示例中string(派生类)到object(基类)的协变逻辑一致。
你提到的“object到dynamic”的转换虽然也能通过编译,但这是利用了dynamic的隐式转换特性,而非协变规则——协变的核心是派生类型向基类类型的转换,而object到dynamic并不符合这个逻辑(dynamic不是object的派生类)。书中的示例是为了明确展示协变的规则,所以选择了符合协变定义的dynamic到object的转换方向。
内容的提问来源于stack exchange,提问作者Alfredo
相关产品推荐
相关产品推荐

