How to decide between C# static and non-static methods?

10,441

Solution 1

KISS. If you don't have to call a constructor, even better.

Also, a method being static should tell you a little about how the function operates:

  • It doesn't operate on variables outside of what's passed to it.
  • It doesn't require any memory other than when the method is called (not counting what is returned from the function)

There are some other important things to note:

  • Static methods in some instances (Java) are not able to be overridden/subclassed, so they are better suited for cases where the implementation will not need to change.
  • Some would argue that static methods are intrinsically difficult to test.

I would also refer to this thread, and a simple google search which frankly provides copious amounts of discussion on this very topic.

Solution 2

Here we go.

First off:

So I tend to use static methods very often (to be independent from a concrete instance - independency is always good thing).

Quite the contrary: when using static methods you're very dependent on the concrete instance.

As far as your Document is concerned, I'd go neither way. You've listed all responsibilities of Document class, which includes aggregation of data, saving itself to the database plus operations on pages and copying.

This is way to much. Per SRP, each "module" (here "module" used as a catch-all term) should have only one reason to change. Your Document has lots of responsibilities, hence it has a whole slew of reasons to change. This is no good.

With that in mind, I'd move all logic to other classes with strictly defined responsibilities. A more or less accepted criterion of what to move was introduced, I believe, by either Herb Sutter or Andrei Alexandrescu, an is as follows: all operations (think methods) that can be performed with an object through its public contract should be moved outside the object in question.


Solution 3

You cannot use static methods to implement an interface, and you cannot override static methods. So using static methods means that you are simply not doing OOP.

Think about how you would implement the following functionality using only static methods?

interface IDocument 
{
   void Print(IDevice targetDevice);
}

IDocument instance;

instance = new PdfDocument();
instance.Print(printer);

instance = new WordDocument();
instance.Print(printer);

Solution 4

My "rule" is:

  • If I don't need to use properties from my class, make it static. (in other words, if the method is not really attached to the class, just there for logic association, use static )

Solution 5

In general if you have method like:

Document.Copy(myDocumentObject, toPath);

I think it is better to use a non-static method, because the first parameter being a Document suggests that it is really an operation on the document.

Share:
10,441
Inno
Author by

Inno

Updated on June 04, 2022

Comments

  • Inno
    Inno almost 2 years

    [Edit]

    My original-question was "Why to decide between static and non-static? Both do the same..."

    Unfortunately it was edited to a C#-specific question what I really wanted to avoid.

    So, let me do some additions:

    When I say interface, I don't mean the C#-keyword-interface but what I understand something like a C++-interface: A set of well defined functions to operate with my object. When saying weaken my interface, I mean I have different functions (static/non-static) that do the same thing. My interface is not well defined anymore when there are different functions to do the same thing.

    So, as Bob the Janitor posted, I can implement a Validate()-function

    Document.Validate(myDocumentObject);    
    

    but also

    myConcreteDocumentObject.Validate();
    

    To get back to my Copy()-example one could implement Copy() like

    myConcreteDocument.Copy(toPath);
    

    but also

    Document.Copy(myConcreteDocumentObject, toPath)
    

    or

    Document.Copy(fromPath, toPath)
    

    when I think of a folder that contains all the files belonging to my Document (in this case I'm not dependent of a concrete instance - but I'm dependent from other things :)).

    In general I'm talking about static methods not static classes (sorry, if I forgot to mension).

    But as Anton Gogolev said I think my Document class is not a good example and not well designed so I think I will have to have a look at the Single Responsibility Principle.

    I could also implement some kind of ManagerClass that operates with my DocumentClass:

    For example:

    myDocumentManagerObject.Copy(myConcreteDocumentObject, toPath);
    

    or

    myDocumentManagerObject.Copy(myConcreteDocumentObject, toPath);
    

    but if I refer to approach 1) I would tend to create objects that perform their tasks by themself rather than other objects (DocumentManager) that do something with my DocumentObject.

    (I hope this will not take the direction of a religious discussion about OOP ;).)

    [/EDIT]


    Old Version:

    At first this seems to be a very basic question like "when to use static methods and when not" but this is something I'm confronted every now and then (and I have difficulties to describe what the real problem is; perhaps it's just to get reasons why (not) to use 1) or why (not) to use 2)).

    (Although I'm using C#-Syntax this is not a C#-restricted problem)

    In OOP there are two approaches (amongst others) of working with objects:

    1) If I want my object to do something, I just tell him to do so:

    myConcreteObject.DoSomething();
    

    It's just like talking to an object.

    2) Or if you're a fan of static methods:

    ObjectClass.JustDoIt();
    

    In some way I think static functions just "feel" better. So I tend to use static methods very often (to be independent from a concrete instance - independency is always good thing).

    So, when designing a class I often have to decide if I take approach 1) or approach 2):

    Imagine you have a class "Document" which should stand for a document that should be saved into a database:

    A Document

    • consists of one or more image files from filesystem (these become the single document pages)
    • has something like a bibliography - fields the user can add information about the document to - which is saved to an extra file
    • and should have some operations like Copy(), AddPage(), RemovePage() etc.

    Now I'm confrontated with several ways to create this class:

    //----- 1) non static approach/talking to objects -----
    Document newDocument = new Document();
    
    // Copy document to x (another database, for example)
    newDocument.Copy(toPath);
    

    I like this: I tell the document to copy itself to database x and the object does so by itself. Nice.

    //----- 2) static approach ----------------------------
    Document.Copy(myDocumentObject, toPath);
    

    Why not? Also nice, feels very handy...

    So, which one to implement? Both? Or putting the static approach to a kind of helper class? Or choose approach 1) and stick with it to not weaken the interface of my Document-class?

    When thinking about both approaches I come to the conclusion that (in theory) one could implement any function as a static function:

    Class.Function(aConcreteClassObject, parameters);
    

    but also non-static:

    aConcreteObject.DoSomething(parameters);
    

    To give a real-world example:

    [EDIT(Added parameter fromPath "Sorry, I forgot")]

    //----- 2) static approach ----------------------------
    File.Copy(fromPath, toPath);    // .Net-Framework-like
    

    [/EDIT]

    but also:

    //----- 1) non static approach ------------------------
    ExampeFileClass fileObject = new ExampleFileClass();
    fileObject.Copy(toPath);
    

    or even (kind of OOP-Overkill):

    //----- 1) non static approach, too -------------------
    fileObject.ToPath = @"C:\Test\file.txt";     // property of fileObject
    fileObject.Copy();                           // copy to toPath
    

    So, why (not) to use 1) or why (not) to use 2)?

    (I would not concentrate on the Document class example too much, since it's more a general question about good class design.)

  • Stefan Steinegger
    Stefan Steinegger about 15 years
    Consider virtual methods and interface implementations. But this is actually as it is proposed by the code analysis ("performance").
  • Stefan Steinegger
    Stefan Steinegger about 15 years
    I have be more precise: this applies to private members only!
  • Lemon
    Lemon about 15 years
    Are you saying that a class should have no public methods?
  • Sergio
    Sergio about 15 years
    Stefan, I think you are not understanding what I said. It's the same as altCognito, just different words.
  • cgp
    cgp about 15 years
    But should those methods when he moves them be static?
  • Dovi
    Dovi about 15 years
    Absolutely no. What I say is that if some operation can be implemented only in terms of public contract of the class in question, this operation should not be a part that class.
  • Dovi
    Dovi about 15 years
    @altCognito It depends. I prefer not to use static methods since they couple code too much.
  • Simon Gibbs
    Simon Gibbs about 15 years
    Your second bullet is a good one since dependencies utilise memory and, of course, you nearly always have some sort of dependency. Therefore, your second bullet actually implies that no interesting method will be static, which feels about right. I disagree that a constructor adds complexity, its adds a line of code, but object instances aid abstraction, reducing complexity and are thereforee KISS compliant.
  • cgp
    cgp about 15 years
    It's twice the code. It introduces using an instance which leads to the absolutely most common failure in programming: Dereferencing a null object. I would cringe if every time I needed to do an xpath query, create a hash (well, some languages anyway), or simply copy a file I had to create an instance.
  • cgp
    cgp about 15 years
    Static methods have their place, though I agree with Anton in that this is not likely one of those places based on what was being proposed.
  • Simon Gibbs
    Simon Gibbs about 15 years
    Well, those aren't really that interesting as methods go.
  • iecanfly
    iecanfly almost 15 years
    So say I have a class Polygon, and want to calculate various (many!) things about it (centre of mass, distance to another polygon, etc). Where should these methods live? If I have a different class for each type of calculation, doesn't it make eg discoverability via IntelliSense very difficult?