WEB开发网
开发学院软件开发C语言 C#编译器对泛型方法调用作类型推断的奇怪问题 阅读

C#编译器对泛型方法调用作类型推断的奇怪问题

 2010-09-30 20:50:06 来源:WEB开发网   
核心提示: 'System.Web.Routing.RouteValueDictionary' does not contain a definition for 'RemoveKeys' and no extension method 'RemoveKeys'

'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

上一页  1 2 3 

Tags:编译器 方法 调用

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接