Unityな日々(Unity Geek)

Unityで可視化アプリを開発するための試行錯誤の覚書

プロパティ(getter/setter)について

通常、C#のクラスは「フィールド」と「メソッド」で構成される。フィールドは「メンバ変数」とも言い、変数(データ)の定義箇所。メソッドはそのままメソッドの定義。

//フィールド
public bool isRunning; 
private float age;

//メソッド
public void CheckAge(){
    ....
}

もうひとつ「プロパティ」というのがある。たとえば次のParameterがプロパティ。

public class Sample : MonoBehaviour {

    private int parameter;
    public int Parameter
    {
        get
        {
            return parameter;
        }
        set
        {
            parameter = value;
        }
    }

    // Use this for initialization
    void Start () {
        Debug.Log("parameter " + parameter);
    }
}

get{…}はgetterと呼ばれ、メソッドと同じく、returnで値を返す。

set{…}はsetterで、暗黙の変数valueを介して値を受け取る。

プロパティは、そのクラスの外側から見ればフィールドのように見え、クラスの内側からみればメソッドのように見える。

//メイン
public class Main : MonoBehaviour {

    public Sample sample;   //サンプルクラス

    void Awake () {
        sample.Parameter = 3;  //プロパティはフィールドのように見える
    }

}

プロパティを使うメリット

プロパティを使うメリットは、条件付きで代入・取得時をおこなったり、代入・取得時にデバッグ出力できること。

    private int parameter;
    public int Parameter
    {
        get
        {
            Debug.Log("Accessed to parameter.");    //parameterが参照された
            return parameter;
        }
        set
        {
            if(value < 5) parameter = value;    //5未満なら代入する
        }
    }   }

また、publicフィールドとの違って、読み込み・書き込みのどちらだけしか許容しない設定も実現でき、より厳密なカプセル化ができる。

取得可・代入禁止

private int parameter;
public int Parameter
    {
        get
        {
            return parameter;
        }
    }

とすると、クラス外からParameterへは代入できなくなる。代入しようとするとエラーになる。

public Sample sample;   //サンプルクラス

void Awake () {
        Debug.Log(sample.Parameter);    //取得可能
        sample.Parameter = 3;           //エラー
    }

代入可・取得禁止

    private int parameter;
    public int Parameter
    {
        set
        {
            parameter = value;
        }
    }

    // Use this for initialization
    void Start () {
        Debug.Log("parameter " + parameter);  
    }

とすると、クラス外からParameter(内部的にはparameter)に代入はできるが、クラス外から値の取得はできない。

void Awake () { sample.Parameter = 3; //代入可能 Debug.Log(sample.Parameter); //エラー }

オートプロパティとその挙動

プロパティは、必ずしもクラス内部のprivate変数に紐づけする必要はない。

すなわち、次のように書くことができる。これは「オートプロパティ」と呼ばれる。

    public int Parameter
    {
        get;
        set;
    }

この場合、外からsetされた値を内側のクラスで使うには、

Debug.Log("Parameter " + Parameter);    //3

のようににアクセスする。(上で、プロパティは、プロパティを定義したクラス内部ではメソッドに見えると書いたが、アクセスする際は()は不要。また、オートプロパティと言っても、自動的に'private parameter`変数に作成・代入されるわけではない)

また、次のようにset;のみだとエラーになる。これはオートプロパティでget;がない場合、値をsetしても取り出せないからだろう。

    public int Parameter
    {
        set;    //エラー
    }

クラス内部からプロパティとしてアクセスする

プロパティは、必ずしもgetでprivate変数に代入しなくてもいい。クラスの内部からでもプロパティとしてアクセスできる。

public class Sample : MonoBehaviour {

    private int parameter;
    public int Parameter
    {
        get
        {
            Debug.Log("Accessed to parameter");
            return parameter;
        }
        set
        {
            parameter = value;
        }
    }

    // Use this for initialization
    void Start () {
        Debug.Log("parameter " + parameter);  //変数として取得
        Debug.Log("Parameter " + Parameter);  //プロパティとして値を取得
        Parameter = 5;                        //プロパティとして代入
        Debug.Log("Parameter " + Parameter);  //プロパティとして値を取得
    }
}

このStart()メソッドの、最初のparameterは内部のprivate変数として、それ以外はプロパティParameterとしてアクセスしている。プロパティとしてアクセスした場合は、getの中の処理を通るので、"Accessed to paramter"がデバッグ表示される。

f:id:yasuda0404:20170415142923p:plain