当一个人接受Expression<Action>
而另一个人接受Expression<Action<T>>
时,重载两种方法的最佳方法是什么?
假设我在(设计糟糕的)类中有以下方法:
void Main()
{
Foo(t => Bar(t));
}
void Foo(Expression<Action> action)
{
"Method 1!".Dump();
}
void Foo<T>(Expression<Action<T>> action)
{
"Method 2!".Dump();
}
void Bar(String thing)
{
// Some bar-like thing
}
现在,可能是我特别昏暗,但我希望从Main
方法调用'方法2'。
对此的唯一限制是我需要传递Expression<...>
,因为我们在其他地方根据表达式树做了一些魔法。
我的理由是这样的:
Action<T>
实际上是与Action
实际发生的是我得到一个编译器错误,我试图将一个参数传递给一个不接受任何参数的Action ...即。 Method 1
正在成为目标。
在旁注中,如果我明确指定泛型参数,这将按预期工作:
Foo<String>(t => Bar(t));
您对此的看法将不胜感激!
答案 0 :(得分:5)
目前,您的两种方法都不适用 - 因为类型推断无法推断出第二种方法T
,第一种方法无效,因为您的匿名函数有一个参数(与{{1}不同})。编译器报告错误,好像它已经执行了重载决策并选择了第一种方法,但它是错误消息并不能真正讲述整个故事的其中一种情况。
如果将方法1的签名更改为:
Action
和方法2的签名:
Foo(Expression<Action> action, string item)
然后类型推断将起作用,并且将调用第二种方法(因为第一种方法不适用)。
如果这两种方法都适用(例如,在上述更改之后,您将非通用方法的第一个参数更改为Foo<T>(Expression<Action<T>> action, T item)
),则最终会以平局为准正常&#34;参数类型的参数&#34;转换 - 但是第一个打破平局规则(在C#5规范的第7.5.3.2节中)是:
- 如果M P 是非泛型方法且M Q 是通用方法,则M P 优于M Q 子>
换句话说,在泛载分辨率方面,非泛型方法比泛型方法更受青睐。
在修复当前代码方面 - 如果没有更多关于您正在努力实现的内容的背景,很难知道如何做到这一点。