Static methods vs instance methods in C#

2019-04-28 17:52发布

问题:

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?

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.

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

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.

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.

回答1:

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

Virtual methods are slightly slower 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.

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



回答2:

Choosing between static and instance methods is a matter of object-oriented design. If the method you are writing is a behavior of 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.



回答3:

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.

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.



回答4:

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:

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.