Aymen Ben Tanfous
Aymen Ben Tanfous

Reputation: 108

C# constructor with optional parameters

I have a simple question about constructors in C#. Will these two code snippets behave the same way?

Code snippet #1:

public class foo
{
    public foo(string a = null, string b = null)
    {
      // do testing on parameters
    }
}

Code snippet #2:

public class foo
{
    public foo()
    {
    }

    public foo(string a)
    {
    }

    public foo(string a, string b)
    {
    }
}

EDIT: And if I add this to the code snippet #1? It may look a really bad idea, but I'm working on refactoring a legacy code, so I'm afraid if I do sth that will cause damage to other piece of that uses that class.

public class foo
{
    public foo(string a = null, string b = null)
    {
       if (a == null && b == null)
            {
                // do sth
            }else if (a != null && b == null)
            {
                // do sth
            }
            if (a != null && b != null)
            {
                // do sth
            }
            else
            {

            }
    }
}

Upvotes: 4

Views: 9999

Answers (3)

Oliamster
Oliamster

Reputation: 512

if your are looking for a way to create an object with optional parameters just create inside your class a static factory method with optional or named parameter:

public class Foo
{
    public Foo(string a, string b, string c) { }

    public static Foo createInstance(string a = null, string b = null, string c = null) => new Foo(a, b, c);
}

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726499

The answer is no, the two are not going to behave the same.

The first snippet does not let your constructor decide if it has been called with a default parameter for a and/or b, or the caller has intentionally passed null. In other words, passing nulls intentionally becomes allowed, because you cannot implement a meaningful null check.

Another aspect in which these two code snippets would definitely differ - using constructors through a reflection:

  • The first snippet would provide one constructor. Reflection callers would need to deal with passing two parameters to it, or allowing optional parameters with binding flags (look at the demo provided by Jcl).
  • The second snippet would provide three separate constructors. Reflection callers would need to pick the one they wish to use.

Upvotes: 9

P.Brian.Mackey
P.Brian.Mackey

Reputation: 44275

No. Try using named arguments. The overload version will not compile. Because a hasn't been given a value in the latter case.

var test = new foo1(b: "nope");
var test2 = new foo2(b: "nope");//CS7036 : There is no argument given that corresponds to the required formal parameter of

Upvotes: 2

Related Questions