C# 方法可以静态化,但应该这样吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/169378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Method can be made static, but should it?
提问by dlamblin
Resharper likes to point out multiple functions per asp.net page that could be made static. Does it help me if I do make them static? Should I make them static and move them to a utility class?
Resharper 喜欢指出每个 asp.net 页面的多个可以静态化的功能。如果我确实让它们静态,它对我有帮助吗?我应该让它们静态并将它们移动到实用程序类吗?
采纳答案by Jeff Yates
Static methods versus Instance methods
10.2.5 Static and instance membersof the C# Language Specification explains the difference. Generally, static methods can provide a very small performance enhancement over instance methods, but only in somewhat extreme situations (see this answerfor some more details on that).
静态方法与实例方法
10.2.5C# 语言规范的静态和实例成员解释了差异。通常,静态方法可以提供相对于实例方法的非常小的性能增强,但仅在某些极端情况下(有关更多详细信息,请参阅此答案)。
Rule CA1822 in FxCop or Code Analysis states:
FxCop 或代码分析中的规则 CA1822 指出:
"After [marking members as static], the compiler will emit non-virtual call sites to these members which will prevent a check at runtime for each call that ensures the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue."
“在 [将成员标记为静态] 之后,编译器将向这些成员发出非虚拟调用站点,这将阻止在运行时对每个调用进行检查,以确保当前对象指针为非空。这可以带来可衡量的性能提升对性能敏感的代码。在某些情况下,无法访问当前对象实例表示正确性问题。”
Utility Class
You shouldn't move them to a utility class unless it makes sense in your design. If the static method relates to a particular type, like a ToRadians(double degrees)
method relates to a class representing angles, it makes sense for that method to exist as a static member of that type (note, this is a convoluted example for the purposes of demonstration).
实用
程序类除非在您的设计中有意义,否则您不应将它们移至实用程序类。如果静态方法与特定类型相关,就像ToRadians(double degrees)
方法与表示角度的类相关,那么该方法作为该类型的静态成员存在是有意义的(注意,这是一个复杂的示例,用于演示目的)。
回答by Josh
It helps to control namespace pollution.
它有助于控制命名空间污染。
回答by Eric Schoonover
You should do what is most readable and intuitive in a given scenario.
在给定的场景中,您应该做最易读和最直观的事情。
The performance argument is not a good one except in the most extreme situations as the only thing that is actually happening is that one extra parameter (this
) is getting pushed onto the stack for instance methods.
除了在最极端的情况下,性能参数不是一个好的参数,因为实际发生的唯一事情是一个额外的参数 ( this
) 被推入堆栈,例如实例方法。
回答by Mun
If the functions are shared across many pages, you could also put them in a base page class, and then have all asp.net pages using that functionality inherit from it (and the functions could still be static as well).
如果这些功能在多个页面之间共享,您也可以将它们放在一个基页面类中,然后让所有使用该功能的 asp.net 页面从它继承(并且这些功能也可以是静态的)。
回答by JasonTrue
I'm sure this isn't happening in your case, but one "bad smell" I've seen in some code I've had to suffer through maintaining used a heck of a lot of static methods.
我确定这不会发生在您的情况下,但是我在某些代码中看到的一种“难闻的气味”,我不得不通过维护使用大量静态方法而遭受痛苦。
Unfortunately, they were static methods that assumed a particular application state. (why sure, we'll only have one user per application! Why not have the User class keep track of that in static variables?) They were glorified ways of accessing global variables. They also had static constructors (!), which are almost always a bad idea. (I know there are a couple of reasonable exceptions).
不幸的是,它们是假定特定应用程序状态的静态方法。(为什么可以肯定,我们每个应用程序只有一个用户!为什么不让 User 类在静态变量中跟踪它?)它们是访问全局变量的美化方式。他们也有静态构造函数(!),这几乎总是一个坏主意。(我知道有几个合理的例外)。
However, static methods are quite useful when they factor out domain-logic that doesn't actually depend on the state of an instance of the object. They can make your code a lot more readable.
然而,静态方法在分解出实际上并不依赖于对象实例状态的域逻辑时非常有用。它们可以使您的代码更具可读性。
Just be sure you're putting them in the right place. Are the static methods intrusively manipulating the internal state of other objects? Can a good case be made that their behavior belongs to one of those classes instead? If you're not separating concerns properly, you may be in for headaches later.
只要确保你把它们放在正确的地方。静态方法是否侵入性地操纵其他对象的内部状态?可以很好地证明他们的行为属于这些类之一吗?如果你没有正确地分离关注点,你以后可能会头疼。
回答by Mark Cidade
Marking a method as static
within a class makes it obvious that it doesn't use any instance members, which can be helpful to know when skimming through the code.
将方法标记为static
类内的方法很明显它不使用任何实例成员,这有助于在浏览代码时了解。
You don't necessarily have to move it to another class unless it's meant to be shared by another class that's just as closely associated, concept-wise.
您不必将它移动到另一个类,除非它打算由另一个在概念上密切相关的类共享。
回答by Austin
Making a method static means you can call the method from outside the class without first creating an instance of that class. This is helpful when working with third-party vendor objects or add-ons. Imagine if you had to first create a Console object "con" before calling con.Writeline();
将方法设为静态意味着您可以从类外部调用该方法,而无需先创建该类的实例。这在使用第三方供应商对象或附加组件时很有帮助。想象一下,如果在调用 con.Writeline(); 之前必须先创建一个 Console 对象“con”;
回答by Jon Skeet
Performance, namespace pollution etc are all secondary in my view. Ask yourself what is logical. Is the method logically operating on an instance of the type, or is it related to the type itself? If it's the latter, make it a static method. Only move it into a utility class if it's related to a type which isn't under your control.
在我看来,性能、命名空间污染等都是次要的。问问自己什么是合乎逻辑的。该方法是对类型的实例进行逻辑操作,还是与类型本身相关?如果是后者,请将其设为静态方法。仅当它与不受您控制的类型相关时才将其移动到实用程序类中。
Sometimes there are methods which logically act on an instance but don't happen to use any of the instance's state yet. For instance, if you were building a file system and you'd got the concept of a directory, but you hadn't implemented it yet, you could write a property returning the kind of the file system object, and it would always be just "file" - but it's logically related to the instance, and so should be an instance method. This is also important if you want to make the method virtual - your particular implementation may need no state, but derived classes might. (For instance, asking a collection whether or not it's read-only - you may not have implemented a read-only form of that collection yet, but it's clearly a property of the collection itself, not the type.)
有时也有其逻辑上作用于一个实例,但不要发生在使用任何实例的状态的方法还没有。例如,如果你正在构建一个文件系统并且你已经有了目录的概念,但你还没有实现它,你可以编写一个返回文件系统对象类型的属性,它总是只是“文件” - 但它在逻辑上与实例相关,因此应该是一个实例方法。如果您想让方法成为虚拟方法,这也很重要 - 您的特定实现可能不需要状态,但派生类可能需要。(例如,询问一个集合是否是只读的——您可能还没有实现该集合的只读形式,但它显然是集合本身的一个属性,而不是类型。)
回答by Benjol
Just to add to @Jason True's answer, it is important to realise that just putting 'static' on a method doesn't guarantee that the method will be 'pure'. It will be stateless with regard to the class in which it is declared, but it may well access other 'static' objects which have state (application configuration etc.), this may not always be a bad thing, but one of the reasons that I personally tend to prefer static methods when I can is that if they are pure, you can test and reason about them in isolation, without having to worry about the surrounding state.
只是添加到@Jason True 的回答中,重要的是要意识到仅将“静态”放在方法上并不能保证该方法将是“纯”的。对于声明它的类,它将是无状态的,但它很可能访问其他具有状态(应用程序配置等)的“静态”对象,这可能并不总是一件坏事,但原因之一我个人倾向于在可能的情况下更喜欢静态方法,因为如果它们是纯的,您可以单独测试和推理它们,而不必担心周围的状态。
回答by G-Wiz
For complex logic within a class, I have found private static methods useful in creating isolated logic, in which the instance inputs are clearly defined in the method signature and no instance side-effects can occur. All outputs must be via return value or out/ref parameters. Breaking down complex logic into side-effect-free code blockscan improve the code's readability and the development team's confidence in it.
对于类中的复杂逻辑,我发现私有静态方法可用于创建隔离逻辑,其中实例输入在方法签名中明确定义,并且不会发生实例副作用。所有输出必须通过返回值或输出/引用参数。将复杂的逻辑分解成无副作用的代码块可以提高代码的可读性和开发团队对它的信心。
On the other hand it can lead to a class polluted by a proliferation of utility methods. As usual, logical naming, documentation, and consistent application of team coding conventions can alleviate this.
另一方面,它可能导致一个类被大量的实用方法所污染。像往常一样,团队编码约定的逻辑命名、文档和一致应用可以缓解这种情况。