简体   繁体   中英

Defining a property within a class

Many times I have seen code where they write a Class like this:

public class Detail
{
    public Detail()
    {
        this.ColumnCtrl = new List<UserControl>();
    }
    public List<UserControl> ColumnCtrl { get; set; }
}

But if I only write the following – it works very fine also:

public class Detail
{
    public List<UserControl> ColumnCtrl { get; set; }
}

Is there any reason to write my get-set Classes like in the first example?

Yes, because the second example will never be initialized when the class is instantiated.

In the first example, the following statement would work:

var detail = new Detail();
detail.ColumnCtrl.Add(new UserControl());

Whereas in the second it would fail with a NullReferenceException unless you initialize it yourself before using it.

The second example does not create a new instance for the property, and if you access it directly after creating an instance of Detail you will throw a null reference exception.

In the first example, they are insuring this will not happen.

The first one always ensures that a instance of a List is returned because the constructor creates a new instance. If you dont have that in the constructor it will return a null in the property.

If you then did:

Detail myInstance = new Detail();
myInstance.ColumnCtrl.Add........  //NullReferenceException is thrown here!

There is a reason to write it the way it is done in the first example. It is the initialization of the property. In the second case if you type:

var detail = new Detail();
var count = detail.ColumnCtrl.Count

you will get exception, because ColumnCtrl is not initialized.

You do not always need to initialize, eg there is no need to initialize when you use dependency injection or if you check for null in a ColumnCtrl getter and initialize it the first time it's requested.

In the second situation the ColumnCtrl is not assigned a value. In The first case you make sure that the ColumnCtrl is assigned an empty list by default.

Your first example initializes the ColumnCtrl property to a value when the Detail class is constructed, where your second one will be left null . If it isn't initialized elsewhere you should expect NullReferenceException s.

As long as you initialize the ColumnCtrl property explicitly before use when using your second example, they are exactly the same thing.

Detail newDetail = new Detail();
newDetail.ColumnCtrl = new List<UserControl>();
newDetail.ColumnCtrl.Add(new UserControl());

An alternative (though slightly more verbose) would be to lazily instantiate the ColumnCtrl property to eliminate the overhead of instantiating it when Detail is constructed:

public class Detail
{
    public Detail()
    {
        this.ColumnCtrl = new List<UserControl>();
    }
    private List<UserControl> columnCtrl = null;
    public List<UserControl> ColumnCtrl
    {
        get 
        {
            // Missing appropriate locking mechanisms for brevity
            if (columnCtrl == null)
                columnCtrl = new List<UserControl>();

            return columnCtrl;
        }
        // The set is not absolutely necessary if you never need to set it
        // from outside of Details but if you do...
        set
        {
            columnCtrl = value;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM