views:

5223

answers:

4

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.

+5  A: 

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.

Mehrdad Afshari
+8  A: 

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.

Jon Skeet
Thanks Jon. Does it make sense now?
Joan Venge
Thanks Jon. I don't have distance type because it's just a float. The instance thing is where I am not sure whether to use. Like I can have the Distance method in Point, but I also want to have say PointToRGBColor, but in my design to me it seems like this RGB method should also be extension.
Joan Venge
Now instancing here makes 100% sense, like the RGB method could be in the Color class. But this prevents me from doing direct usage of the functionality if there must be an instance. For Point, it's ok because it's the most basic type one needs to have to use it.
Joan Venge
Hmm... I'm not really following the Point/RGB example. It might make sense as an extension method if it's only suitable in some contexts (rather than always, for any point, in any usage). I would advise not going *too* overboard with extension methods.
Jon Skeet
+3  A: 

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.

DefLog
+1  A: 

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.

Daniel Earwicker
Thanks, yeah Position is a property in my Person class. But these operations are constructed by the user via a schematic graph. So I wanted to have a unified way of doing it, but also having the ability to use them directly without creating any schematic items in the UI.
Joan Venge
Btw I didn't get the second part. You mean personA.Distance(personB) and Extensions.Distance is the same?
Joan Venge
First I ask personA to work out the distance to personB, then I ask personB to work out the distance to personA. The two people are swapped. By making it a method, you imply that the person is figuring it out in their own unique, which is misleading. I'm recommending against adding a Distance method
Daniel Earwicker
I don't know what you mean by the user constructing the operations. Could you go into more detail in your question?
Daniel Earwicker
Thanks. You mean I should have a static Distance method? Or are you talking about the instance method? Another thing to note is I am trying to have LINQ style syntax, like person.A().B().C().D() ...
Joan Venge
As for user making these operations, it's like these stuff is all in t he UI, so the user says for example "new person" then sets some values and add it to the UI, so I have person A, B, C, then I add a Distance item, and link it to any 2 persons. When it's executed, I have to construct it correctly
Joan Venge
How complex can it get? I'm having trouble understanding why you'd need to write hard-coded expressions. The user sets up a diagram, so the relationships are all dynamic. What does it mean to "execute" it?
Daniel Earwicker
So the diagram can contain an unlimited number of connections. And this Person, Distance is just an example. But say you have Add, Subtract and many many more. So in effect the graph is also not linear. It's a tree where I have to update it to shwo the final result.
Joan Venge
So if it was a calculator using a schematic UI, you could do stuff like perform some operations and then store it as something then pass this result to some other operation in the graph.
Joan Venge
Right, so it almost works like a graphical expression that needs to be evaluated? Given that level of flexibility, I can't understand how you'd ever be hard-coding a chain of calls like in your "LINQ style" example. Instead your code will be looping through lists asking objects to evaluate things.
Daniel Earwicker
And the lists will be constructed by the user - you won't know anything definite at compile time.
Daniel Earwicker