Construtors and Properties question

Quick question about initializing properties in c#…I have the following class with private variables and getters/setters:

using UnityEngine;

public class BikeUpgrades {

	// Singleton access
	private static readonly BikeUpgrades _instance = new BikeUpgrades();
	
	
	#region Private variables
	
	// Camera switch variables
	private float _camSwitchDuration;		// Duration in seconds of the time the 2d camera will last
	private int _camSwitchCount;				// Amounts of camera switch available to the player
	
	#endregion
	
	#region Constructor
	public BikeUpgrades () 
	{
		if( _instance != null )
		{
			//Debug.LogWarning ("Cannot have two instances of singleton.");
			return;
		}
		
		_camSwitchDuration = 2.0f;
		_camSwitchCount = 1;      // Does not call the "set{}" accessor
		CamSwitchCount = 1;       // Does call the "set{}" accessor
	}
	#endregion
	
	#region Getters and Setters
	public static BikeUpgrades Instance
	{
		get{ return _instance; }
	}
	
	public float CamSwitchDuration 
	{
		get{ return _camSwitchDuration; }
		set{ _camSwitchDuration = Mathf.Clamp( value, 2f, 10f ); }
	}
	
	public int CamSwitchCount  
	{
		get{ return _camSwitchCount; }
		set{ _camSwitchCount = Mathf.Clamp( value, 2, 10 ); }
	}
	
	
	#endregion
}

In the example above, when initializing _camSwitchCount = 1 in the constructor, the property CamSwitchCount returns 1 even tho the setter clamps the value between 2 and 10, because the setter isn’t being called.
When initializing CamSwitchCount = 1 in the constructor, the property CamSwitchCount returns 2 because the setter is being called and it works like planned.

My question is, should you initialize the private variables at all, or should you just initialize the property itself, since this seems to actually return the correct value?

I have been using properties for a while now, but never really delved into them too deep. Any guidance/tips/help would be very appreciated as far as good/bad practice and whether or not I should initialize a property in the class’s constructor or just initialize the private variable which the property returns?

Stephane

2 Answers

2

The usual rule is that in class functions, you use the actual variable. Gives a small speed boost, and it’s assumed that when you’re monkeying inside the class that you have it “in your head,” know what you are doing and know when to break rules made for “outsiders” (like setting camCount to 1 at the start.)

In Unity, properties are not exposed in the Inspector, so stick with just regular vars for anything you want to designer to set for a gameObject.

Constructors also work funny for things created by the engine. In http://unity3d.com/support/documentation/ScriptReference/index.Writing_Scripts_in_Csharp_26_Boo.html they recommend against them for scripts on gameObjects. For classes which you create in code, I believe they are fine.

Also, the point of Properties is you can not use them, and swap them in later. For example, hitPoints is fine as a public int. Later, when you need changing HP to also update some text field, you can create private int _HP; and swap in a hitPoints property which sets both. Outsiders using hitPoints=10; are fine before and after. Compare to C++, where you do need to establish getHP()/setHP() at the start, so outsiders know whether to use orc1.hitPoints=10; or orc1.setHP(10);.

Owen, thanks a lot for the explanation! To clarify, when you say at the beginning: "you use the actual variable", is the actual variable 'CamSwitchCount' (the property), or '_camSwitchCount' (the private var)? Also, what exactly is considered as "outsiders" in my code above? Again, thx a lot for your time, it really helps understand things better :)

Sorry mixing technical and non. CamSwitchCount is a Property, _CSC is a variable. Member functs traditionally use either the Prop to save coding or the var for speed. Nothing in your code is an "outsider." I meant someone else using BikeUpgrades.Instance.CamSwitchCount doesn't know or care they are vars/props.

I agree with this, a public property is not under control : beeing public means that it can be accessed and modified by other. You should only expose properties that represent the interface with other script. A private property is only known by the implementation and is used internally. Then you can have public accessor that let you expose userfull informations.

I use the following pattern for my properties in C# :

// This is editable through Unity's inspector
[SerializeField]
private int InternalMyVar = 5;
public int MyVar
{
    get { return InternalMyVar; }
    private set { InternalMyVar = value; }
}

I think this is cool as it let you set the default value through the inspector and expose your property to other scripts

Not really what I was asking for, but thanks anyways for your answer as I didn't know you could reveal properties in the inspector!

Send me the floating script, i shall(if possible) change it according to your problem...