1

I have 2 classes: Track.cs and TrackList.cs, Track.cs is used to save data from a track. In TrackList I want to save objects of Track.cs in a List.

This is the code i currently have:

class TrackList
{
    private List<Tracks> tracks;

    public TrackList()
    {
        tracks = new List<Tracks>();
    }
    public TrackList(List<Tracks> tracks)
    {
        this.tracks = new List<Tracks>(tracks);
    }

}

What I understand from this is that, When I create an object of this class: TrackList TC = new TrackList() the list will get initialized if I don't add parameters, But when I send a Track.cs object as a parameter it will add to the track list.

But someone said I should use this.tracks = tracks; instead of this.tracks = new List<Tracks>(tracks);. But I don't get why, because if I use this.tracks = tracks; I have not used the = new List<Tracks>; part so it won't be initialized. Or am I thinking incorrectly?

Is it the same as if I do this

int id;

public MyClass()
{
    id = 0;
}

public MyClass(int id)
{
    this.id = id;
}

Also in my assignment it says the parameter list needs to be assigned to the list in the TrackList class.

Edit 2

My new though after a comment private List<Tracks> tracks; is a reference to nothing atm. this.tracks = tracks makes the tracks list ^ reference to the list that was send with parameters this.tracks = new List<Tracks>(tracks); will create a new list, So the tracks list will now reference that new list, and the new list has the same content as the list that was send with parameters.

So with the method i use(the last one) there are 2 list in existence with the same content but private List<Tracks> tracks; will reference that new list and i dont know what happens to the list that was send with the parameters.

Edit 3

It seems that my assumption in Edit 2 was correct. Thank you guys a lot for your help. Cheers!

7
  • 1
    The "someone" is correct. You already declared it and here you are simply passing the existing "tracks" parameter into the Class to another container. No need for another "new". Passing the existing List to "this.tracks" is initialising it. Commented Mar 15, 2016 at 20:19
  • 1
    Also, you need to use constructor chaining. public TrackList() : this(new List<Tracks>()) { }. Using chaining prevents bugs from cropping up when you have constructor overloads. The smell for this is that you have multiple constructors instantiating/setting the same fields/properties. Commented Mar 15, 2016 at 20:23
  • But I have never said tracks = new List<Tracks>(); so doesn't that mean it is not initialized? Or does it automatically initialize when I add objects to it? Commented Mar 15, 2016 at 20:24
  • new initializes an object of a given type. You accept an object of type List<Tracks>, so whoever news up this instance is the one passing you the object. You can verify it is not null, if you want. I'd strongly suggest you pick up a copy of CLR Via C#. Skip the first two chapters and read. Should take about a day. Commented Mar 15, 2016 at 20:26
  • 1
    No, you are assigning an existing list (instantiated elsewhere) to your local variable Commented Mar 15, 2016 at 20:52

4 Answers 4

3

the parameter in the constructor has the same name as your attribute.

Change the attribute or the parameter in the constructor.

Try this:

class TrackList
{
    private List<Tracks> _tracks;

    public TrackList()
    {
        _tracks = new List<Tracks>();
    }
    public TrackList(List<Tracks> tracks)
    {
        _tracks = new List<Tracks>(tracks);
    }

}
Sign up to request clarification or add additional context in comments.

1 Comment

This does not matter, I use This.tracks so it will use the list.
1

At first, I'd like you to edit your question to consolidate your class names. For my answer, I assume the Track class to be called Track and the list class to be called TrackList (you use TrackClass and TrackList, Track and Tracks).
And the field tracks of your TrackList class I'll call _tracks to not mix it with the constructor argument tracks.


The field tracks of your TrackList class takes a reference of an instance of type List<Track>. In your constructor you assign a newly created instance by calling

_tracks = new List<Track>(tracks);

This creates a new List<Track> that is filled with the Track instances in the list passed as argument.

If you assign the argument like

_tracks = tracks;

you set the field to the instance that was passed as argument (it is initialized, to the same value as tracks).

The difference between those two ways is the following:

Track track = new Track();
List<Track> myTracks = new List<Track>();
myTracks.Add(track);

TrackList trackList = new TrackList(myTracks);

myTracks.Add(new Track());

In the last line, I add another track to the list previously created. In the code you show, this will not be added to the list contained by TrackList, because the field contains another new list.
If you assigned _tracks = tracks, TrackList would contain the same list, so the last line from above would added the new Track to the list in trackList, too (well, not "too", it is just the same list the Add was called on).


So to decide between the two ways you should ask yourself: Should it be possible that the list inside your TrackList class can be changed from outside the TrackList class?" _tracks is a private field, so I guess you don't want anyone to change the content of that list from outside. So your way of creating a new list filling it with the elements of the list provided as argument seems the better way.

Hope I could make my self understandable.

1 Comment

Thank you, I edited my post(See below Edit 2). Would that be correct?
0

If you use this.tracks = tracks, then someone else that has created the initial list could update it without using the TrackList class. This is working, and this prevent an array allocation. But the TrackList class lose control over the list.

Comments

0

for my case, I used this example.

It is better to use constructors when passing outside arguments

class TrackList
    {
        private List<Tracks> tracks;
        public List<Tracks> Tracks {get;set;}=new List<Tracks>();
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.