Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can't use object initializers with immutable objects. They require settable properties.</p> <p>An immutable object implies "does not change after creation". Making <code>Name</code> a constructor parameter neatly expresses that principle.</p> <p>If the object gets too complicated for a comprehensible constructor, you can also use the Builder pattern. Generally, the builder itself will have mutable properties (that you can use in object initializers), and its .Build() method will create the actual instance.</p> <p><strong>EDIT (OP):</strong> I'm going to add my own example of a builder that I cooked up here, then accept this answer since it proposes a reasonable solution.</p> <pre><code>class MyObject { public class Builder { public Builder() { // set default values Name = String.Empty; } public MyObject Build() { return new MyObject(Name); } public string Name { get; set; } } private static int nextId; protected MyObject(string name) { Id = ++nextId; Name = name; } public int Id { get; private set; } public string Name { get; private set; } } </code></pre> <p>You can then construct an instance of it with the following:</p> <pre><code>MyObject test = new MyObject.Builder { Name = "foo" }.Build(); </code></pre> <p><strong>EDIT</strong>: This is my take on the pattern:</p> <pre><code>public abstract class Builder&lt;T&gt; { public static implicit operator T(Builder&lt;T&gt; builder) { return builder.Build(); } private bool _built; public T Build() { if(_built) { throw new InvalidOperationException("Instance already built"); } _built = true; return GetInstance(); } protected abstract T GetInstance(); } </code></pre> <p>Here is your example as implemented with <code>Builder&lt;T&gt;</code>. It takes advantage of the scoping rules of nested types to access the private setter:</p> <pre><code>public class MyObject { private static int nextId; protected MyObject() { Id = ++nextId; } public int Id { get; private set; } public string Name { get; private set; } public sealed class Builder : Builder&lt;MyObject&gt; { private MyObject _instance = new MyObject(); protected override MyObject GetInstance() { // Validate properties here return _instance; } public string Name { get { return _instance.Name; } set { _instance.Name = value; } } } } </code></pre> <p>It has an implicit conversion to the target type, allowing you to do this:</p> <pre><code>MyObject myObject = new MyObject.Builder { Name = "Some name" }; </code></pre> <p>Or this:</p> <pre><code>public void Foo(MyObject myObject) // ... Foo(new MyObject.Builder { Name = "Some name" }); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload