Nat*_*lor 2 c# boxing unboxing anonymous-methods
假设以下代理"调用者"签名:
FuncCaller<T>(Func<T, bool> predicate)
Run Code Online (Sandbox Code Playgroud)
和匹配方法:
bool MyFunc(object o)
Run Code Online (Sandbox Code Playgroud)
什么时候T是引用类型,我可以像这样MyFunc 隐式调用:
FuncCaller<String>(MyFunc) // valid
Run Code Online (Sandbox Code Playgroud)
相反,如果T是值类型,则在隐式调用MyFunc时会出现编译错误:
FuncCaller<Int32>(MyFunc) // invalid ("No overload for 'MyFunc(object)' matches delegate 'System.Func<int?,bool>'")
Run Code Online (Sandbox Code Playgroud)
我的问题是,鉴于这两个例子,为什么MyFunc在隐式调用时调用无效,但在明确调用时有效如下:
FuncCaller<Int32>(i => MyFunc(i)) // valid
Run Code Online (Sandbox Code Playgroud)
我认为这是与拳击和拆箱类型相关的某种问题?
小智 6
是的,这正是它的本质.
FuncCaller<Int32>(i => MyFunc(i)) // valid
Run Code Online (Sandbox Code Playgroud)
创建一个匿名函数,其参数类型Int32和返回值bool,除了将参数转换为object和调用之外什么都不做MyFunc.这就像你写的那样
FuncCaller<Int32>(MyFunc2)
Run Code Online (Sandbox Code Playgroud)
在哪里MyFunc2定义为
bool MyFunc2(Int32 o) { return MyFunc(o); }
Run Code Online (Sandbox Code Playgroud)
转换参数是一个无操作,因此当类型是引用类型时是不必要的,这就是参数类型object为足够接近参数类型的委托的函数的原因string:参数类型已经是object.
转换参数是一种实际操作,当类型为值类型时,无法绕过该操作.
值得指出的是
FuncCaller<Int32>(MyFunc)
Run Code Online (Sandbox Code Playgroud)
永远不会简写
FuncCaller<Int32>(i => MyFunc(i))
Run Code Online (Sandbox Code Playgroud)
即使它可能表现得几乎相同.前者MyFunc直接传递函数,后者在它周围创建一个包装函数.这里需要包装函数.
| 归档时间: |
|
| 查看次数: |
623 次 |
| 最近记录: |