Mediator object in auto-generated object

Is there a way to automatically initialize an object without creating it in the constructor?

Actually, I have something like:

public List<Object> Products { get; set; }
public MyClass()
{
    this.Products = new List<Object>();
}

      

But instead, I would like to directly link my list without specifying in my constructor of my class with something like:

public List<Object> Products = new List<Object>(); { get; set; }

      

Is there a trick for this?

+3


source to share


3 answers


As Jon Skeet says:

It's unfortunate that there is no way to do this right now. You have to set a value in the constructor. (Using constructor chaining can help avoid duplication.)

The auto-implemented properties are handy right now, but they can certainly be better. I don't want me to initialize as often as the auto-update read-only property, which can only be set in the constructor and will be read-only. It is possible that both will be fixed in C # 5, which I hope will address the immutability of the problem. (I don't think any of these are planned for C # 4.)

Source: C # Auto Properties Initialization




If you need to initialize property

without using the constructor

, you need to use backing field

.

Example

class Demo
{
    private List<object> myProperty = new List<object>();
    public List<object> MyProperty
    {
        get { return myProperty; }
        set { myProperty = value; }
    }
}

      

+3


source


I think you are asking if you can give an initial value to an auto-implemented property. The answer to this question is "no".

You can write the property by hand though:

private List<Product> products = new List<Product>();

public List<Product> Products
{
    get { return products; }
    set { this.products = value; }
}

      

Do you really need a setter? Do you need clients to be able to replace the value of a variable with another list? You may find that you only need a read-only property, in which case you could write:



private readonly List<Product> products = new List<Product>();

public IList<Product> Products { get { return products; } }

      

Note that you can still use a collection initializer here, like

Foo foo = new Foo
{
    Products = { new Product("foo"), new Product("bar") }
};

      

+4


source


In C # there is currently no auto-generated property (although VB.NET can do this automatically). This is what I have often wished for myself. So you can manually roll your own property or use the constructor.

In any case, you will have some code that you don't need to write to do this (manual property with no constructor and auto-property with constructor).

Interestingly, however, IL is different from the two options. When you have a manual property with a backing field using an initializer, it will be executed before the base class constructor in C #:

MyClass..ctor:
IL_0000:  ldarg.0     
IL_0001:  newobj      System.Collections.Generic.List<System.Object>..ctor
IL_0006:  stfld       UserQuery+MyClass._products
IL_000B:  ldarg.0     
IL_000C:  call        System.Object..ctor
IL_0011:  nop         
IL_0012:  ret         

      

When using an auto-initialized property in a constructor, will execute after the base class constructor in C #:

MyClass..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  nop         
IL_0007:  nop         
IL_0008:  ldarg.0     
IL_0009:  newobj      System.Collections.Generic.List<System.Object>..ctor
IL_000E:  call        UserQuery+MyClass.set_Products
IL_0013:  nop         
IL_0014:  nop         
IL_0015:  ret       

      

I'm only saying this as a curiosity, as writing code that depends on the initialization order in .NET can be risky (the initialization order is actually slightly different from VB.NET and C #)

+1


source







All Articles