1

I know an empty method without any good reason is a code smell, but it can be required for constructors.

What would be a good way to write an empty constructor among the following?

class A
{
    private int a;
    public A(int v)
    {
         a = v;
    }
}

class B : A
{
     // 1
     public B(int v) : base(v) { }

     // 2
     public B(int v) : base(v)
     { } 

     // 3
     public B(int v) : base(v)
     {
     } 
}
3
  • 1
    An empty method isn't a code smell. It's part of my favorite pattern. Commented Mar 25, 2021 at 3:28
  • This question has some issues, let me fix at least two of them. However, if you prefer 1, 2, or 3 is totally opinionated. In my team, we would accept them all, since all are equally readable, but other teams may have a different taste.
    – Doc Brown
    Commented Mar 25, 2021 at 5:12
  • 7
    How you write the brackets of an empty constructor is a very trivial issue, and is a matter of style. Any pros and cons are practically not worth discussing; just pick one. Commented Mar 25, 2021 at 6:05

2 Answers 2

5

This is how I do it:

    public B(int v)
        : base(v)
    {
        // Empty
    }

Motivation is that I want to be explicit on the fact that I intend this to be an empty code block. When I come back to this code some time in the future, I'd know that it is not that I forgot to write the code.

Consider also to extend the comment with the an explanation of why the code block should not be removed, in particular if removing it does not break the build.

3
  • The last paragraph seems to gloss over the strongly suggested existence of tests ("if removing it does not break the build") and that developers shouldn't need explicit explanation to understand that calling a base constructor isn't superfluous code that "does nothing". If such a level of developer guidance is needed, then you're going to have to explicitly explain many things in your codebase, and comments are not the best teaching tool to ensure your developers have a general understanding of the language.
    – Flater
    Commented Mar 25, 2021 at 10:17
  • @Flater I don't want to wait for tests to run to discover I should not have removed this code block. And put me on the bad developers, because I began doing this for myself. I guess I should be writing more comments then.
    – Theraot
    Commented Mar 25, 2021 at 15:13
  • I like the idea of being explicit about emptiness. To my team, side-by-side braces { } is an indication of explicit emptiness and can be quickly recognized by the eye. It's okay if your team is different though.
    – John Wu
    Commented Mar 25, 2021 at 17:08
-2

If the class won't be used by third parties and you don't need an overloaded constructor, don't write an empty constructor.

But...

Imagine you already shipped the product, and third parties use your class. A few months later there's a new requirement that makes you add a constructor with an argument.

Now, by doing so, the C# compiler no longer generates a default constructor. If you don't add an empty constructor explicitly, the third party code will be break.

In my opinion, you should always define empty constructors (one liner) for public classes used by third parties.

public B() { }
4
  • 2
    This answer, though it contains some wisdom, does not match the question, which was not about constructors with no arguments, but about constructors with an empty function body.
    – Doc Brown
    Commented Mar 25, 2021 at 5:16
  • 1
    "If you don't add an empty constructor explicitly, the third party code will be break." So will your unit tests and that is when you know you need to add the empty constructor. Don't add empty constructors just because you may not remember someone uses them. Your tests do. You do have unit tests right?
    – nvoigt
    Commented Mar 25, 2021 at 7:48
  • 1
    It makes no sense to blanket add parameterless constructors without observing the specific context. If the new version of the software now intentionally forces there to be parameters in the class constructor, and does not provide a parameterless constructor, then it's correct that third party code can no longer use a parameterless constructor anymore. This is why versioned releases matter. If customers don't want their parameter-constructor-using code to break, they simply should not be upgrading to this newer version which no longer allows the parameterless constructor.
    – Flater
    Commented Mar 25, 2021 at 9:53
  • 1
    [..] In other words, if there was a use for a parameterless constructor, your code would contain that parameterless constructor. By not having it, you are stating very clearly that this class should only be instantiated using the parametered constructors that the class does contain. In such a case, the third party consumer's code did not wrongly break. It broke the way you specifically wanted it to, by no longer allowing the use of the parameterless constructor.
    – Flater
    Commented Mar 25, 2021 at 9:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.