C#编译器对泛型方法调用作类型推断的奇怪问题
2010-09-30 20:50:06 来源:WEB开发网'System.Web.Routing.RouteValueDictionary' does not contain a definition for 'RemoveKeys' and no extension method 'RemoveKeys' accepting a first argument of type 'System.Web.Routing.RouteValueDictionary' could be found.
这个错误提示和之前的不同,它告诉我们缺少RemoveKeys方法,而并没有要求我们补全泛型参数。但是一旦补全了泛型参数就没有问题了:
values.RemoveKeys<RouteValueDictionary, string, object>(...);
但是您会愿意写这样的代码吗?
因此,最后我不得不补充了另一个方法,误打误撞地绕开了“强制指定泛型参数”的方法:
public static IDictionary<TKey, TValue> RemoveKeys<TKey, TValue>(
this IDictionary<TKey, TValue> source, IEnumerable<TKey> keys)
{
foreach (var key in keys)
{
source.Remove(key);
}
return source;
}
这个方法直接使用了IDictionary<TKey, TValue>类型,而不是把它作为泛型参数的限制条件——问题就这么解决了。别问我为什么,我也不知道……
虽然从表面上解决了这个问题,但是它带来的限制也是很明显的:虽然新的方法也可以作用在字典类型上,但是新方法只能返回IDictionary<TKey, TValue>类型,旧的方法返回的则是原有的类型(如RouteValueDictionary)。返回原有的类型就可以利用其Fluent Interface,让代码编写更为方便。
这个应该算是C#编译器的bug吧,不知道有没有其他朋友遇到过。C#编译器半吊子的类型推断特性,总是能够不断给我们“惊喜”。还是一些函数式语言的类型推断最为强大,如Haskell或F#。在编写代码的时候,只会由于F#的类型推断功能太强而降低了代码的可读性(因此有时候我们甚至于会“主动”加上类型),而不会在某个“是人都能看出来类型”的情况下,编译器缺如瞎了一般非要我们提供具体类型。
出处:http://www.cnblogs.com/JeffreyZhao/archive/2009/08/20/type-inference-bug-in-csharp.html
更多精彩
赞助商链接