ericdc
ericdc

Reputation: 11289

How to instantiate a new instance of a property in C#

In VB.Net I am using a variation of this so when a the SearchModel is used there is an empty list of Tags ready to go.

Public Class SearchModel
    Public Property Tags As New List(Of TagDetails)
End Class 

A simple conversion results in this but "Tags" is null:

public class SearchModel
{
    public List<TagDetails> Tags { get; set; }
}

Is this an acceptable way to create the "Tags" property and create a new empty list at the same time?

public class SearchModel
{
    public List<TagDetails> Tags = new List<TagDetails>();
}

Or should I go through all of this ceremony?

public class SearchModel
{
  private List<TagDetails> _TagDetails;
    public List<TagDetails> Tags
    {
        get { return _TagDetails ?? (_TagDetails = new List<TagDetails>()); }
        set { _TagDetails = value; }
    }
}

Upvotes: 4

Views: 329

Answers (5)

JG in SD
JG in SD

Reputation: 5607

If you want to keep the lazy instantiation of the list:

public class SearchModel
{
  private Lazy<List<TagDetails>> tags = new Lazy(() => new List<TagDetails>());

  public List<TagDetails> Tags
  {
    get { return this.tags.Value; }
  }
}

However with this you will not be able to set the value.

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460308

The conventional way is using a constructor:

public class SearchModel
{
    public SearchModel()
    {
        Tags = new List<TagDetails>();
    }
    public List<TagDetails> Tags { get; set; }
}

Upvotes: 8

Tony Hopkinson
Tony Hopkinson

Reputation: 20330

There are also good arguments for not exposing the concrete list class at all. I'd certainly question whether a setter was wise, you could get a right mess in terms of object life times and the garbage collector with that.

public class SearchModel
{
    private List<TagDetails> _tags;

    public SearchModel()
    {
        _tags = new List<TagDetails>();
    }

    public IEnumerable<TagDetails> Tags {get {return _tags;}}

}

Would have been my first attempt and then and add any other list type methods I needed to, Clear, append etc.

Upvotes: 0

Dave Doknjas
Dave Doknjas

Reputation: 6542

The most straight-forward conversion is the following (which is what VB is doing behind the scenes):

public class SearchModel
{
    private List<TagDetails> _Tags = new List<TagDetails>();
    public List<TagDetails> Tags
    {
        get
        {
            return _Tags;
        }
        set
        {
            _Tags = value;
        }
    }
}

Upvotes: 0

Gromer
Gromer

Reputation: 9931

Instantiate it in the constructor:

public class SearchModel
{
    public List<TagDetails> Tags { get; set; }

    public SearchModel()
    {
        Tags = new List<TagDetails>();
    }

    public SearchModel(List<TagDetails> tagDetails)
    {
        Tags = tagDetails;
    }
}

I did that in C# since you had most of your code in C#. You can keep the automatic property doing it that way. You can also add an overloaded constructor that takes in a list to use (delete that if you don't want it).

Upvotes: 5

Related Questions