[英]Boxing & Unboxing: Why doesn't this delegate match?
Assuming the following delegate "caller" signature: 假定以下委托人为“主叫方”签名:
FuncCaller<T>(Func<T, bool> predicate)
and a matching method: 和匹配方法:
bool MyFunc(object o)
When T
is a reference type, I can invoke MyFunc
implicitly like so: 当
T
是引用类型时,我可以像这样隐式调用MyFunc
:
FuncCaller<String>(MyFunc) // valid
Conversely, when T
is a value type, I get a compilation error when calling MyFunc implicitly: 相反,当
T
为值类型时,隐式调用MyFunc时出现编译错误:
FuncCaller<Int32>(MyFunc) // invalid ("No overload for 'MyFunc(object)' matches delegate 'System.Func<int?,bool>'")
My question is, given these two examples, why is the call to MyFunc
invalid when invoked implicitly, but valid when invoked explicitly like so: 我的问题是,给出这两个示例,为什么对
MyFunc
调用在隐式调用时无效,而在显式调用时有效,如下所示:
FuncCaller<Int32>(i => MyFunc(i)) // valid
I assume this is some kind of issue related to boxing and unboxing of types? 我认为这是与装箱和拆箱有关的某种问题吗?
Yes, that's exactly what it is. 是的,就是这样。
FuncCaller<Int32>(i => MyFunc(i)) // valid
creates an anonymous function, with a parameter of type Int32
, and a return value of bool
, which does nothing but convert the parameter to object
, and calls MyFunc
. 创建一个匿名函数,其参数类型为
Int32
,返回值bool
,除了将参数转换为object
,什么都不做,然后调用MyFunc
。 It's as if you'd written 就像你写的一样
FuncCaller<Int32>(MyFunc2)
where MyFunc2
is defined as MyFunc2
被定义为
bool MyFunc2(Int32 o) { return MyFunc(o); }
Converting the parameter is a no-op and therefore unnecessary when the type is a reference type, which is why a function with a parameter type of object
is close enough for a delegate with a parameter type of string
: the parameter type is already an object
. 转换参数是无操作的,因此在类型是引用类型时是不必要的,这就是为什么具有
object
参数类型的object
对于具有string
参数类型的委托足够接近的原因:参数类型已经是一个object
。
Converting the parameter is a real operation that cannot be bypassed when the type is a value type. 转换参数是一个实际操作,当类型是值类型时,不能绕过该操作。
It's worth pointing out that 值得指出的是
FuncCaller<Int32>(MyFunc)
isn't ever shorthand for 从来都不是简写
FuncCaller<Int32>(i => MyFunc(i))
even though it may behave almost the same way. 即使它的行为几乎相同。 The former passes the
MyFunc
function directly, the latter creates a wrapper function around it. 前者直接传递
MyFunc
函数,后者围绕它创建包装函数。 That wrapper function is necessary here. 包装函数在这里是必需的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.