2011-01-10 133 views
34

我正在寻找一些利用C#应用程序中静态工具类的扩展方法的优点和缺点。扩展方法vs静态工具类

例如,扩展方法列中的加号是通过类名调用而非类似“StringUtils”的方便。但是,con会是它可以模糊框架内部和非框架之间的界限。

+0

[评估在C#中使用扩展方法的成本/好处=> 3.0](http:// stackoverflow。com/questions/1644743/evaluation-cost-benefits-of-using-extension-methods-in-c-3-0) – 2011-01-10 11:56:22

+0

在这里发布了一个类似的问题:http://stackoverflow.com/questions/487904/what-优点 - 扩展 - 方法 - 你找到并在这里:http://stackoverflow.com/questions/1644743/evaluating-cost-benefits-of-using-extension-methods-in-c-3-0 – HABJAN 2011-01-10 11:35:25

回答

45

我会说,是它模糊了什么是在框架和什么不是之间的界限:您可以使用自己的代码作为框架代码,运行框架类型自然。

扩展方法不应该被任意使用,当然 - 它不像全部是静态方法应该成为扩展方法。

我尝试将它看作是该方法是否在逻辑上“运行”其第一个参数。如果你能够将它作为一个实例方法包含在内,它会作为实例方法吗?

您可能没有意识到的“con”:如果扩展类型后来添加了一个适用于相同参数的同名实例方法,则您的调用代码将在您下次启动时透明地启动该实例方法重新编译。例如,在.NET 4中,Stream获得了CopyTo ...我之前编写了一个CopyTo扩展方法,该方法不会被调用。没有警告说这种情况正在发生,所以你必须警惕。

一个告诫:扩展方法还没有足够长时间才能真正建立最佳实践。你应该仔细衡量所有的意见(甚至 - 或者特别是 - 我自己的意见)。

+0

7年后,最佳实践已经建立? – Sipo 2017-12-03 11:05:55

10

在一天结束时,两种方法都使用静态方法。

string foo = "bob"; 
StringUtils.DoSomething(foo); 

string foo = "bob"; 
foo.DoSomething(); 

之间唯一的区别是语法糖。它归结为个人偏好和编码标准。有时候方法名称可能足够描述,不能保证看到静态类名。其他时候包含类名更有意义。

最后,扩展方法也可以作为静态方法调用!

string foo = "bob"; 
StringExtensions.DoSomething(foo); 

以上使用的代码与第二个示例中的代码相同,但调用方式不同。考虑到最后一点,您可以真正创建静态实用程序类作为扩展方法,然后根据需要调用它们。

4

我个人喜欢通过扩展方法提供的readabilty和链调用(隐式提供可读性)。

1) Readability: 
    bool empty = String.IsNullOrEmpty (myString) 
    //in comparison to 
    bool empty = myString.IsNullOrEmpty(); 

2) Chain calls: 
    var query = Enumerable.Range(0, 10) 
         .Where(x => x % 2 == 0) 
         .Reverse(); 
    //instead of 
    var query = Enumerable.Reverse(Enumerable.Where(Enumerable.Range(0, 10), x => x % 2 == 0)); 

con是您的扩展方法,如果您不小心做到了,它可以被实例成员重写。我个人不喜欢这个。至少编译器应该发出尖叫声,如果它发生在同一个程序集中。