Hernando N
Hernando N

Reputation: 305

Field vs { get;set } vs { get=>field; set=>field = value;} - C# Unity

I have this code and my objective is to modify the field value to be used in any method in the abstract class. What I understand is that:

But the editor (variables are not modified there, it is hard code) doesn't throw the expected result, it is, to modify the speed field value. A clear and concise explanation is appreciated. enter image description here

Upvotes: 0

Views: 5702

Answers (3)

Sindri Jóelsson
Sindri Jóelsson

Reputation: 369

[SerializeField] marks fields.

Properties are syntactic sugar for methods getting/setting a value.

When you declare a property like public int Speed {get;} a hidden backing field is generated by the compiler which is where the value is actually stored, this field is private and so will not be serialized automatically by Unity's serializer. (Additionally the compiler will generate a method public int get_Speed() which is the implementation of the property's get you can verify this by declaring this method yourself, the compiler should complain about a member with the same signature already existing.)

C# 7.3 added Auto-implemented property field-targeted attributes, allowing you to do this:

[field:SerializeField] public int Speed {get;}

This will apply the SerializeField attribute to the hidden generated field and Unity should serialize it normally. Note that the name of this hidden field will have the special name <Speed>k__BackingField something to keep in mind if you plan to implement a custom inspector or property drawer.

Upvotes: 3

derHugo
derHugo

Reputation: 90639

You are confusing the terms "field" and "property". Properties can implement additional behavior in the getter and setter.

First of all: Unity does not serialize properties!

This limits the purposes of properties in Unity to the runtime.

So most of the time will want to go for a pattern like

[SerializeField] private int a;
public int A => a;

This e.g. serves the purpose that you can assign a value via the editor, edit it by the class itself but allow others only readonly access => Encapsulation.

And of course for completeness it can perform additional sanity checks like e.g.

private const int min = -3;
private const int max = 17;
private bool allowSet;

[SerializeField] private int a;
public int A 
{
    get => a;
    set 
    {
        if(allowSet) a = Mathf.Clamp(a, min, max);
    }
}

An auto-property (in my eyes) is barely needed except you want to directly limit the access like

public int b { get; private set;}

This allows only this class to write but everyone else to read this value

So when something is useful is mostly subjective and depends on the situation.


Now looking at your code there is absolutely no relationship between Speed - speed and FireRate-fireRate! They are completely independent fields and properties.

The confusion here is probably due to the display names that the Inspector creates. It automatically makes all field names capitalized so

[SerializeField] private int _example;

will be displayed as Example.

You most probably would simply go for

[SerializeField] protected float Speed;
[SerializeField] protected float FireRate;

Upvotes: 1

MarkSouls
MarkSouls

Reputation: 999

In your code, fireRate and FireRate are completely separate field/property as well as speed and Speed. Modifying fireRate won't affect FireRate and vice versa.

SerializeField is used to serialize fields not properties. In both cases only fields(fireRate and speed) are serialized.

Try below code:

    [SerializeField] public int a;
    [SerializeField] public int b { get; set; }
    [SerializeField] public int c => a;

Unity doesn't serialize property by default and only a will be serialized.

Upvotes: 3

Related Questions