扩展方法与静态实用程序类

AJM*_*AJM 40 .net c# extension-methods design-patterns

我正在寻找在C#应用程序中使用扩展方法而非静态实用程序类的一些优缺点.

例如,扩展方法列中的一个加号是通过类名调用而不是像"StringUtils"那样的方便.但是,它可能会模糊框架内部和非框架之间的界限.

Jon*_*eet 50

我想说专业人士是它模糊了框架内部和非框架之间的界限:您可以像框架代码一样自然地使用自己的代码,对框架类型进行操作.

当然,扩展方法不应该被任意使用 - 它并不像所有静态方法都应该成为扩展方法.

我试着将其视为该方法是否在逻辑上"操作"其第一个参数.如果您能够将其作为实例方法包含在内,它作为实例方法是否有意义?

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

一个警告:扩展方法已经存在很长时间,以至于最佳实践才能真正建立起来.你应该仔细权衡所有意见(甚至 - 或者特别是 - 我自己的意见).

  • @Sipo:不是真的:) (5认同)
  • 7年后,是否已建立最佳实践? (2认同)

Sco*_*ott 12

在一天结束时,两种方法都使用静态方法.唯一的区别

string foo = "bob";
StringUtils.DoSomething(foo);
Run Code Online (Sandbox Code Playgroud)

string foo = "bob";
foo.DoSomething();
Run Code Online (Sandbox Code Playgroud)

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

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

string foo = "bob";
StringExtensions.DoSomething(foo);
Run Code Online (Sandbox Code Playgroud)

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

  • 作为旁注:语法不是唯一的区别.扩展方法不使用隐式转换,静态方法也是如此.就是我的长龙; IntExtension.DoSomething(myLong)`工作正常,但``myLong.DoSomething()`无法编译.它是扩展方法的预期行为,但与常规静态方法不同. (6认同)

Sri*_*nth 5

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

 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));
Run Code Online (Sandbox Code Playgroud)

Con是您的扩展方法,如果您不小心这样做,则实例成员可以覆盖它。我个人不喜欢这样。如果是在同一程序集中发生的话,至少编译器应该大喊大叫。