扩展方法vs静态实用工具类

时间:2022-10-23 21:02:29

I'm looking for some pros and cons for using extension methods over static utility classes in a C# app.

我正在寻找在c#应用程序中使用扩展方法而不是静态实用程序类的一些优点和缺点。

For instance, a plus in the extension methods column is the convinience of calling by the class name rather than something like "StringUtils". But a con would be that it can blur the lines between what is in the framework and what isn't.

例如,扩展方法列中的一个加号是通过类名而不是“StringUtils”调用的对流性。但一个错误是,它可以模糊框架中的内容和不框架中的内容之间的界限。

3 个解决方案

#1


47  

I would say that a pro is that it blurs the lines between what is in the framework and what isn't: you can use your own code as naturally as framework code, operating on framework types.

我要说的是,pro版模糊了框架中的内容和不包含的内容之间的界限:您可以像使用框架代码一样自然地使用自己的代码,对框架类型进行操作。

Extension methods shouldn't be used arbitrarily, of course - it's not like all static methods should become extension methods.

当然,扩展方法不应该被任意使用——并不是所有的静态方法都应该成为扩展方法。

I try to think of it as whether the method is logically operating "on" its first parameter. Would it make sense as an instance method, if you were able to include it as an instance method?

我试着把它看作是方法是否在逻辑上运行它的第一个参数。如果您能够将它包含为实例方法,那么它作为实例方法是否有意义呢?

A "con" which you may not be aware of: if the extended type later adds an instance method of the same name which is applicable with the same parameters, your calling code will transparently start calling that instance method next time you recompile. For example, Stream gained CopyTo in .NET 4... I'd previously written a CopyTo extension method, which then wouldn't be called. There's no warning that this is occurring, so you have to be on your guard.

您可能没有注意到的“con”:如果扩展类型稍后添加了同名的实例方法,该方法适用于相同的参数,那么下次重新编译时,您的调用代码将透明地开始调用该实例方法。例如,流在。net 4中获得CopyTo…我之前写过一个CopyTo扩展方法,然后不会调用它。没有警告说这正在发生,所以你必须警惕。

One caveat: extension methods haven't been around for long enough for best practices to really become established. You should weigh up all opinions (even - or perhaps especially - my own ones) carefully.

需要注意的是,扩展方法还没有足够的时间来建立最佳实践。你应该仔细权衡所有的意见(甚至——或许尤其是——我自己的意见)。

#2


11  

At the end of the day, both approaches use static methods. The only difference between

最后,两种方法都使用静态方法。唯一的区别

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

and

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

is syntactic sugar. It boils down to personal preference and coding standards. Sometimes the method name can be descriptive enough to not warrant seeing the static class name. Other times it makes more sense to include the class name.

是语法糖。它归结为个人偏好和编码标准。有时,方法名可能具有足够的描述性,因此不需要查看静态类名。其他时候,包含类名更有意义。

Finally, extension methods can be invoked as static methods too!

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

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

The above uses the same code as in the second example, but is invoked differently. With this last tidbit in mind, you could really create static utility classes as extension methods and then invoke them however you wish.

上面的代码与第二个示例中的代码相同,但调用方式不同。记住这最后一点,您可以将静态实用程序类创建为扩展方法,然后按自己的意愿调用它们。

#3


4  

I personally like readabilty and chain calls(implicitly provides readability) that is provided by Extension methods.

我个人喜欢由扩展方法提供的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 is your extension method can be overriden by instance member if you accidentally do it. Personally I dont like this. At least compiler should have screamed, if it is happening with in the same assembly.

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

#1


47  

I would say that a pro is that it blurs the lines between what is in the framework and what isn't: you can use your own code as naturally as framework code, operating on framework types.

我要说的是,pro版模糊了框架中的内容和不包含的内容之间的界限:您可以像使用框架代码一样自然地使用自己的代码,对框架类型进行操作。

Extension methods shouldn't be used arbitrarily, of course - it's not like all static methods should become extension methods.

当然,扩展方法不应该被任意使用——并不是所有的静态方法都应该成为扩展方法。

I try to think of it as whether the method is logically operating "on" its first parameter. Would it make sense as an instance method, if you were able to include it as an instance method?

我试着把它看作是方法是否在逻辑上运行它的第一个参数。如果您能够将它包含为实例方法,那么它作为实例方法是否有意义呢?

A "con" which you may not be aware of: if the extended type later adds an instance method of the same name which is applicable with the same parameters, your calling code will transparently start calling that instance method next time you recompile. For example, Stream gained CopyTo in .NET 4... I'd previously written a CopyTo extension method, which then wouldn't be called. There's no warning that this is occurring, so you have to be on your guard.

您可能没有注意到的“con”:如果扩展类型稍后添加了同名的实例方法,该方法适用于相同的参数,那么下次重新编译时,您的调用代码将透明地开始调用该实例方法。例如,流在。net 4中获得CopyTo…我之前写过一个CopyTo扩展方法,然后不会调用它。没有警告说这正在发生,所以你必须警惕。

One caveat: extension methods haven't been around for long enough for best practices to really become established. You should weigh up all opinions (even - or perhaps especially - my own ones) carefully.

需要注意的是,扩展方法还没有足够的时间来建立最佳实践。你应该仔细权衡所有的意见(甚至——或许尤其是——我自己的意见)。

#2


11  

At the end of the day, both approaches use static methods. The only difference between

最后,两种方法都使用静态方法。唯一的区别

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

and

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

is syntactic sugar. It boils down to personal preference and coding standards. Sometimes the method name can be descriptive enough to not warrant seeing the static class name. Other times it makes more sense to include the class name.

是语法糖。它归结为个人偏好和编码标准。有时,方法名可能具有足够的描述性,因此不需要查看静态类名。其他时候,包含类名更有意义。

Finally, extension methods can be invoked as static methods too!

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

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

The above uses the same code as in the second example, but is invoked differently. With this last tidbit in mind, you could really create static utility classes as extension methods and then invoke them however you wish.

上面的代码与第二个示例中的代码相同,但调用方式不同。记住这最后一点,您可以将静态实用程序类创建为扩展方法,然后按自己的意愿调用它们。

#3


4  

I personally like readabilty and chain calls(implicitly provides readability) that is provided by Extension methods.

我个人喜欢由扩展方法提供的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 is your extension method can be overriden by instance member if you accidentally do it. Personally I dont like this. At least compiler should have screamed, if it is happening with in the same assembly.

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