Home > Net >  Why can't I use automatically implemented getters and setters with a List? (Unity, C#)
Why can't I use automatically implemented getters and setters with a List? (Unity, C#)

Time:12-04

I'm trying to wrap my head around getters and setters a bit better.

I know I can use automatically implemented getters and setters like public Vector3 Position { get; set; } as shorthand for

private Vector3 _position;
public Vector3 Position
{ 
    get {return _position;} 
    set{_position = value;} 
}

BUT what I can't figure out is why that doesn't work for Lists. If I try to declare a list like:

List<Vector3> Positions { get; set;}

Unity throws a Null Reference Exception at me.

But if I use the long-form:

private List<Vector3> _position = new List<Vector3>();
public List<Vector3> Position
{ 
    get {return _position;} 
    set{_position = value;} 
}

It works just fine. I assume this has something to do with the way lists are declared, but I'd like to know what exactly is going on here.

CodePudding user response:

When you write this

List<Vector3> Positions { get; set;}

you declare a property of type List<Vector3>, but you don't assign anything to it, so attempts to dereference it, e.g.

Positions.Add(vec3);

will throw a NullReferenceException. You can continue using auto-properties and initialize your list like:

List<Vector3> Positions { get; set;} = new List<Vector3>();

CodePudding user response:

C# has the concept of Value Types and Reference Types. Value types "act like integers" - a variable of a value type actually stores the value, and it has a default value (usually some sort of zero).

Reference types, on the other hand, are references to something in memory, and variables of a reference type do NOT store the actual object, instead they store the address of the actual object. If you haven't initialized it, a reference type variable defaults to zero, a.k.a. null.

Vector3 is a value type. List is a reference type. This explains the different behavior, and why your second sample with List works - in that case you've explicitly created and initialized the list object and pointed your reference at it.

This is also why, in general, it's a bad idea to have a set method on a List property. You don't want to let external callers completely change which list it's pointing at, you want to change the contents of the actual list you already have.

  • Related