我正在寻找在C#应用中使用扩展方法与静态工具类之间的优缺点。
例如,使用扩展方法的优点是通过类名方便调用,而不是像“StringUtils”这样。但缺点是它可能会模糊框架中存在的内容和不存在的内容之间的界限。
我正在寻找在C#应用中使用扩展方法与静态工具类之间的优缺点。
例如,使用扩展方法的优点是通过类名方便调用,而不是像“StringUtils”这样。但缺点是它可能会模糊框架中存在的内容和不存在的内容之间的界限。
我觉得它的优点是模糊了框架内外的界限:你可以像使用框架代码一样自然地使用自己的代码,操作框架类型。
当然,不应该随意使用扩展方法 - 并不是所有的静态方法都应该成为扩展方法。
我试着考虑这个方法是否在逻辑上“对”它的第一个参数进行操作。如果您能将其包括为实例方法,那么它是否有意义呢?
可能你没有意识到的一个“缺点”:如果扩展类型后来添加了一个与相同参数适用的同名实例方法,那么在下一次重新编译时,你的调用代码将自动开始调用那个实例方法。例如,在 .NET 4 中,Stream
增加了CopyTo
方法... 我之前写了一个 CopyTo
扩展方法,然后就无法被调用了。这发生时没有任何警告,所以你必须保持警惕。
一个警告:扩展方法还没有存在足够长的时间,以便真正建立最佳实践。你应该仔细权衡所有意见(甚至 - 或者也许特别是 - 我自己的意见)。
归根结底,两种方法都使用静态方法。唯一的区别在于
string foo = "bob";
StringUtils.DoSomething(foo);
和
string foo = "bob";
foo.DoSomething();
是一种语法糖。它归结为个人喜好和编码标准。有时方法名可以足够描述,不需要看到静态类名。而其他情况下,则更合理包含类名。
最后,扩展方法也可以作为静态方法调用!
string foo = "bob";
StringExtensions.DoSomething(foo);
上面的代码与第二个示例中使用的代码相同,但调用方式不同。请记住这个小技巧,您可以创建静态实用程序类作为扩展方法,然后以任何希望的方式调用它们。
long myLong; IntExtension.DoSomething(myLong)
可以正常工作,但 myLong.DoSomething()
将无法编译通过。这是扩展方法的预期行为,但与常规静态方法不同。 - NOtherDev我个人喜欢扩展方法提供的可读性和链式调用(隐式提供可读性)。
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));
如果您不小心这样做,您的扩展方法可能会被实例成员覆盖。个人而言,我不喜欢这种情况发生。至少编译器应该会警告,在同一程序集中发生此类情况时。