user9855465
user9855465

Reputation:

Two almost identical constructors

In my application I have a class which I use with an object initializer. But I think that it's better to specify a constructor for the class. So I made the following code:

My class:

public class Person
{
    public string Name { get; set; }
    public string SecondName { get; set; }
    public string Address { get; set; }
    public int Age { get; set; }
    public DateTime BirthDate { get; set; }
    public string Url { get; set; }
}

Now I need to specify a constructor. But the Url property should be optional. I don't know how to do this. Because when I specify two different constructors one with the url and one without it, it feels like duplicated code.

public Person(string name, string secondName, string address, int age, DateTime birthDate, string url)
{
    Name = name;
    SecondName = secondName;
    Address = address;
    Age = age;
    BirthDate = birthDate;
    Url = url; // This is optional
}

Is it bad to specify two constructors that are almost the same or is that the best solution. Or should I just use the object initializer

Edit: To clarify my question a bit. I'm now creating an object from this class as followed.

Person person = new Person(name, secondName, address, age, birthDate)
if(hasUrl)
{
    person.Url = "theUrlHere"
}

Upvotes: 1

Views: 172

Answers (3)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112342

As the URL is the last parameter, you can make it optional (since C# 4.0). Just assign it the desired default value in the parameter list.

public Person(
    string name, string secondName, string address, int age, DateTime birthDate,
    string url = null)
{ ... }

Now you can omit the URL when calling the constructor.

var p1 = new Person("John", "Smith", "New York", 17, new DateTime(2001, 3, 12));
var p2 = new Person("Sue", "Miller", "York", 22, new DateTime(1995, 7, 5), "www.sue-mi.com");

See: Named and Optional Arguments (C# Programming Guide)

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500505

Options:

  • Just provide a parameterless constructor, and use object initializers to populate the properties
  • Provide two constructor signatures, almost certainly delegating from "the one without the URL" to "the one with the URL". For example:

    public Person(string name, string secondName, string address,
                  int age, DateTime birthDate)
        : this(name, secondName, address, age, birthDate, null)
    {
    }
    
    public Person(string name, string secondName, string address,
                  int age, DateTime birthDate, string url)
    {
        // Set all the properties here
    }
    
  • Provide a single constructor and use an optional parameter for the URL, e.g.

    public Person(string name, string secondName, string address,
                  int age, DateTime birthDate, string url = null)
    

Note the = null part for the url parameter, which makes it an optional parameter. If the calling code doesn't provide a value, the compiler will pass null (the default value as specified here) implicitly.

In the cases where you provide these "long" constructor signatures, you may also want to provide a parameterless one for users who would prefer to use object initializers.

Upvotes: 0

Sebastian Hofmann
Sebastian Hofmann

Reputation: 1438

You could create two constructors and call the first one from the second:

public Person(string name, string secondName, string address, int age, DateTime birthDate)
{
    Name = name;
    SecondName = secondName;
    Address = address;
    Age = age;
    BirthDate = birthDate;
}

public Person(string name, string secondName, string address, int age, DateTime birthDate, string url)
    : this (name, secondName, address, age, birthDate)
{
    Url = url;
}

Or you could make the url parameter optional:

public Person(string name, string secondName, string address, int age, DateTime birthDate, string url = null)
{
    Name = name;
    SecondName = secondName;
    Address = address;
    Age = age;
    BirthDate = birthDate;
    Url = url;
}

Upvotes: 1

Related Questions