C#中的静态方法与实例方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/596367/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 09:41:15  来源:igfitidea点击:

Static methods vs instance methods in C#

c#.netgarbage-collectionclrmethods

提问by Joan Venge

For an application I am writing, I want to have extreme extensibility and extension methods seem to give me what I want, plus the ability to call them without an instance, which I need too.

对于我正在编写的应用程序,我希望具有极高的可扩展性,并且扩展方法似乎可以满足我的需求,并且能够在没有实例的情况下调用它们,这也是我所需要的。

I remember reading that static methods are faster than instance methods but don't get the advantages of GC. Is this correct?

我记得读过静态方法比实例方法更快,但没有获得 GC 的优势。这样对吗?

It's highly unlikely I will change my design unless I find a superior alternative by design not speed. But still for extra information I wanna know the differences in speed, GC, etc.

除非我通过设计而不是速度找到更好的替代方案,否则我不太可能改变我的设计。但仍然需要额外的信息,我想知道速度、GC 等方面的差异。

EDIT: Thanks. More info: Let's say we have a Person class:

编辑:谢谢。更多信息:假设我们有一个 Person 类:

class Person

which can have an instance Distance method so like:

它可以有一个实例距离方法,例如:

this.Distance (Person p)

This is great, but this doesn't give me the ability to calculate the distance between 2 points (say Point3), without creating instances of the Person class.

这很棒,但这并不能让我在不创建 Person 类的实例的情况下计算两点之间的距离(比如 Point3)。

What I want to do is this:

我想做的是这样的:

class Person (no Distance methods)

but extension methods of Distance:

但距离的扩展方法:

Distance (this Person, Person)
Distance (this Point3, Point3)

This way I can both do:

这样我都可以做到:

myPerson.Distance (yourPerson)

and

Extensions.Distance (pointA, pointB)

EDIT2: @Jon, yeah I think that was what was meant by (don't get the advantages of GC), but I somehow thought that the static methods create this burden/overhead.

EDIT2:@Jon,是的,我认为这就是(不要获得 GC 的优势)的意思,但我以某种方式认为静态方法会造成这种负担/开销。

采纳答案by Jon Skeet

What do you mean by "don't get the advantages of GC"? Methods aren't garbage collected - instances are.

“没有得到GC的优势”是什么意思?方法不是垃圾收集的 - 实例是。

Virtual methods are slightlyslower than non-virtual ones, and I guess there's that pesky null check before any instance method, but it's not significant. Go with the most appropriate design.

虚拟的方法是稍微慢于非虚的,我想没有任何实例方法之前那个讨厌的空检查,但它并不显著。选择最合适的设计。

Static methods are a pain for testing though - for instance, if you authenticate in method Foo()by calling some static method, then when you're testing Foo()you can't make it just call a mock authenticator (unless the static method itself lets you do that). If you give the original instance of whatever you're testing a mock implementation of some interface containing an Authenticate()method, however, you can make it behave however you want.

尽管如此,静态方法对于测试来说是一种痛苦 - 例如,如果您Foo()通过调用一些静态方法在方法中进行身份验证,那么当您进行测试时,Foo()您不能让它只调用模拟身份验证器(除非静态方法本身允许您这样做)。但是,如果您为正在测试的任何对象提供了包含Authenticate()方法的某个接口的模拟实现的原始实例,则可以使其按照您想要的方式运行。

EDIT: In this case, it sounds like what you really need is an instance method on your Pointtype to calculate the distance between two points ("this" one and another) - or potentially a static factory method on the Distancetype.

编辑:在这种情况下,听起来您真正需要的是Point类型上的实例方法来计算两点(“这个”一个和另一个)之间的距离 - 或者可能是Distance类型上的静态工厂方法。

回答by Mehrdad Afshari

Choosing between static and instance methods is a matter of object-oriented design. If the method you are writing is a behaviorof a an object, then it should be an instance method. If it doesn't depend on an instance of an object, it should be static.

在静态方法和实例方法之间进行选择是面向对象设计的问题。如果你编写的方法是一个对象的行为,那么它应该是一个实例方法。如果它不依赖于对象的实例,则它应该是静态的。

Basically, static methods belong to a type while instance methods belong to instances of a type.

基本上,静态方法属于一种类型,而实例方法属于一种类型的实例。

回答by DefLog

If by being faster you mean the code inside the method is executed faster, then no. A code in a static method is just as fast as code in a non static method.

如果更快是指方法中的代码执行得更快,那么不。静态方法中的代码与非静态方法中的代码一样快。

If your are talking about the overhead of performing the call to the method it becomes a little more complex. It is common for languages as Java that instance calls have more overhead. In C# this is not the case however because instance methods are not virtual by default.

如果您正在谈论执行对方法的调用的开销,它会变得稍微复杂一些。对于像 Java 这样的语言来说,实例调用有更多的开销是很常见的。但是在 C# 中情况并非如此,因为实例方法默认情况下不是虚拟的。

So a virtual method has slightly more overhead than a non virtual method. Static methods cannot be virtual, but instance methods can be declared virtual.

因此,虚方法比非虚方法的开销略高。静态方法不能是虚拟的,但实例方法可以声明为虚拟的。

As for Garbage collection, this is mainly relevant for fields, not methods. Static fields can be accessed from everywhere in the code so the garbage collector can't determine if the reference will be used again, so it is never collected.

至于垃圾收集,这主要与字段相关,而不是与方法相关。可以从代码中的任何地方访问静态字段,因此垃圾收集器无法确定是否会再次使用该引用,因此永远不会收集它。

回答by Daniel Earwicker

Based on your example, I would write a static utility function to find the distance between two points:

根据您的示例,我将编写一个静态实用程序函数来查找两点之间的距离:

public static class Geometry
{
    public static double GetDistanceBetween(Point a, Point b) { ... }
}

And then I would give Person a property called Position that returned a point. So I could write:

然后我会给 Person 一个名为 Position 的属性,它返回一个点。所以我可以写:

double distance = Geometry.GetDistanceBetween(personA.Position, personB.Position);

It's practically in English already - why make it more obscure? If you make Distance a method, then you can write:

它实际上已经是英语了——为什么要让它更模糊?如果你让距离成为一个方法,那么你可以写:

personA.Distance(personB)

or:

或者:

personB.Distance(personA)

There's no difference between those two orderings, and yet the use of method-call syntax suggests that there might be a difference.

这两种顺序没有区别,但是方法调用语法的使用表明可能存在差异。