简体   繁体   English

装箱与拆箱:为什么此代表不匹配?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM