AllOutOfSalt
AllOutOfSalt

Reputation: 1492

use default property value in C# constructor initializer

Consider the following class:

class Foo
{
    public string Bar { get; set; } = "foobar";
}

And this piece of code:

var foo = new Foo {
    Bar = bar == null
            ? null
            : bar
};

Obviously, the value of Bar would be null after the execution of this code (suppose that bar = null).

I want the constructor initializer to use default property value in given cases (e.g. when bar is null). I want to know if there is an easier way to do this instead of using:

if (bar == null) {
    foo = new Foo();
} else {
    foo = new Foo { Bar = bar };
}

Or

foo = new Foo();
if (bar != null)
    foo.Bar = bar;

Upvotes: 3

Views: 3289

Answers (5)

Fabjan
Fabjan

Reputation: 13676

Well, you can simplify it by using null coalescing operator:

  var foo = new Foo();
  foo.Bar = bar ?? foo.Bar;

Or you can change property to check for null values and ignore them :

    private string _bar = "foobar";
    public string Bar
    {
        get { return _bar; }
        set { _bar = value ?? _bar;  }
    }

Then you can use this code to instantiate Foo :

   var foo = new Foo() { Bar = bar };

Note that now if bar is null its value will be ignored in property's setter.

Upvotes: 2

George Mamaladze
George Mamaladze

Reputation: 7921

The cleanest OO way of doing that would be by using overloaded constructor and a factory method:

    class Foo
    {
        public Foo Create(string bar)
        {
            return bar == null ? new Foo() : new Foo(bar);
        }

        public Foo() : this("foobar")
        {
        }

        public Foo(string bar)
        {
            Bar = bar;
        }
        public string Bar { get; }
    }

Upvotes: 1

slawekwin
slawekwin

Reputation: 6310

Easiest and most readable (IMHO) solution would be:

var foo = new Foo();
if (bar != null)
    foo.Bar = bar;

There is no way to make the validation like you suggested in the initializer (at least not as of C# 6). You could use some constructs with extracting your default to constant like other answers here suggest, but this takes away from readability and does not make using the class easier - you have to know about implementation (default value in the constant) details, which breaks the encapsulation.

If your main concern is about code style, I suggest you get used to ifs, because there is nothing wrong with them and are easy to understand for someone else maintaining your code or yourself in a few months.

If there is something else you need, like validation of the property value, you need to place it in the setter itself (and you should have stated so in the question).

Upvotes: 1

webnoob
webnoob

Reputation: 15924

You could do:

class Foo
{
    public const string BarDefault = "foobar";
    public string Bar { get; set; } = BarDefault;
}

var foo = new Foo { Bar = bar ?? Foo.BarDefault };

It has an advantage of having all your defaults in consts at the top of the class but I don't really see the point personally. It does however mean you don't need a conditional statement (kind of).

Upvotes: 0

haim770
haim770

Reputation: 49095

If you'll extract the default value of the Bar property to a static field:

public class Foo
{
    public string Bar { get; set; } = defaultBarValue;

    public static string defaultBarValue = "foobar";
}

You'll be able to do this:

new Foo
{
    Bar = bar != null ? bar : Foo.defaultBarValue,
};

But I doubt it's worth the effort...

Upvotes: 0

Related Questions