Hap*_*mad 0 c# overloading type-inference compiler-errors
通常,C#编译器对方法绑定和类型参数推断很聪明.但我似乎已经难倒了.
class Obj
{
void Handler( int a, int b ) { }
Obj() { Method( "", Handler ); }
public void Method<T>( T t, Action<T> action ) { }
public void Method<T, U>( T t, Action<U, U> action ) { }
}
Run Code Online (Sandbox Code Playgroud)
该Method调用导致编译器错误:
参数2:无法从'方法组'转换为'System.Action'.
为什么编译器没有注意到调用符合第二个重载?我可以通过使调用更明确,如在Method<string, int>( "", Handler )或中编译它Method( "", (Action<int, int>)Handler ).但为什么这有必要呢?
让我们看看安东尼的建议,并考虑一下:
class Obj
{
void Handler( int a, int b ) { }
Obj() { Method( "", Handler ); }
public void Method<T, U>( T t, Action<U, U> action ) { }
}
Run Code Online (Sandbox Code Playgroud)
重载解析失败.为什么?好吧,我们必须推断T和U.显然T是字符串.什么是U?
这一点很重要:在我们知道Handler是什么之后,我们推断出U是什么.现在,您可能会说我们知道Handler是什么,因为它只有一件事.但是没有C#规则说如果方法组中只有一个方法可以自动赢得重载决策游戏.规则是Handler的含义是通过在与Handler关联的方法组上运行重载决策来确定的.重载决策考虑了参数,我们没有Handler的任何参数,因为我们可能拥有的唯一参数列表是(U,U),而U是我们首先想要确定的.
因此,重载决议失败了.现在,如果我们有:
class Obj
{
double M(string s) { }
Obj() { Method( "", M ); }
public void Method<T, U>(T t, Func<T, U> f) { }
}
Run Code Online (Sandbox Code Playgroud)
这很好.我们推断T是字符串,现在我们可以对M进行重载决策,确定M意味着double M(string s),现在我们知道U是双精度的.
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |