C#程序员最易犯的编程错误

2019-12-26 13:38:31王振洲

 

  1. namespace System.Linq {  public static class Enumerable {  ... 
  2.  // the reference here to “this IEnumerable<TSource> source” is   // the magic sauce that provides access to the extension method Sum 
  3.  public static decimal Sum<TSource>(this IEnumerable<TSource> source,            Func<TSource, decimal> selector);  ... 
  4. }  } 
?

  可是扩展方法和其它静态方法有什么不同之处,是什么确保我们可以在其它类访问它?

  扩展方法的显著特点是第一个形参前的this修饰符。这就是编译器知道它是一个扩展方法的“奥妙”。它所修饰的参数的类型(这个例子中的IEnumerable<TSource>)说明这个类或者接口将显得实现了这个方法。

  (另外需要指出的是,定义扩展方法的IEnumerable接口和Enumerable类的名字间的相似性没什么奇怪的。这种相似性只是随意的风格选择。)

  理解了这一点,我们可以看到上面介绍的sumAccounts方法能以下面的方式实现:
 

  1. public decimal SumAccounts(IEnumerable<Account> myAccounts) {   return Enumerable.Sum(myAccounts, a => a.Balance); 
?

  事实上我们可能已经这样实现了这个方法,而不是问什么要有扩展方法。扩展方法本身只是C#的一个方便你无需继承、重新编译或者修改原始代码就可以给已存的在类型“添加”方法的方式。

  扩展方法通过在文件开头添加using [namespace];引入到作用域。你需要知道你要找的扩展方法所在的名字空间。如果你知道你要找的是什么,这点很容易。

  当C#编译器碰到一个对象的实例调用了一个方法,并且它在这个对象的类中找不到那个方法,它就会尝试在作用域中所有的扩展方法里找一个匹配所要求的类和方法签名的。如果找到了,它就把实例的引用当做第一个参数传给那个扩展方法,然后如果有其它参数的话,再把它们依次传入扩展方法。(如果C#编译器没有在作用域中找到相应的扩展方法,它会抛措。)