機能の拡張 -プロパティ-

ホームC#プログラミング応用講義 > プロパティ

目次

プロパティは使うもの

応用講義をここまで読んでこられた方に、「プロパティを使ったことがない」人はいないでしょう。
プロパティは「Text プロパティ」「Size プロパティ」など、さまざまなものがあって、それらを使って設定を行うのは非常にポピュラーでした。

しかし、応用講義ではプロパティを定義することができるようになります。

とはいえ、いざプログラムを組むときはプロパティはすでに定義してあるもの、すなわち .NET Framework のクラスライブラリに定義済みのプロパティを利用することが多いと思います。
それはそれでフル利用すべきですし、自分でプロパティを定義しなくともいい場合は多くあります。

ところが、プロパティを利用することで圧倒的に安全さが高められます。そしてわかりやすくなります。

下のサンプルではある int 型の変数があり、それには 0 から 10 まで入れられるようにしたいです。
ところが変数だと int 型の範囲の整数なら何でも入れることができます。これでは安全性が確保されているとはいえません。

このように安全性の確保をしたいときはよくありますし、すべきときもよくあります。
ここで定義する「自分で定義するプロパティ」はそのようなときに威力を発揮します。

基本事項

プロパティはメンバの一員です。ですから変数やメソッドと同じ場所に記述します。
ちなみにこのプロパティを習得することで、「メンバ」のすべての定義および利用方法が習得できたことになります。

プロパティは非常におもしろいものです。プロパティで重要なのは「get」「set」「value」(ゲット・セット・バリュー)の3つですが、それぞれ重要な意味を持っています。

this.Text = textBox1.Text;
このステートメントは「textBox1 に入力された値をフォームのタイトルバーに表示」を意味しますが、素直にプログラムコードだけを見ると「右辺の textBox1.Text を左辺の this.Text に代入」を意味します。

さて、みなさんは textBox1.Text すなわち右辺の立場に立ってみてください。こいつは Text プロパティを取得します。ただ取得するだけで、特に変わった動きはしていません。

忙しいですが、次は this.Text すなわち左辺の立場に立ってみてください。こっちは右辺の値が入ってきます。すんわち設定されています。こっちも特に変わった動きはしていません。


自分でプロパティを定義する際、上の2つの立場に立って内容を定義します。
取得は「get」ステートメントブロックに、設定は「set」ステートメントブロックに定義します。

特に設定の場合は右辺が左辺のプロパティに代入されますから、プロパティ定義部分でその右辺の値を取得できなければなりません。
その取得は常に「value」というキーワードで取得できます。

これが言葉で説明してもなかなかわからないんですよね。けれどプロパティの場合はサンプルを見ればよくわかりますからサンプルにうつりましょう。

サンプル

using System;

class TestClass
{
    private int zero_To_ten = 0;
    public int ZeroToTen
    {
        get
        {
            return zero_To_ten;
        }
        set
        {
            if (0<=value && value<=10)
                zero_To_ten = value;
            else
                zero_To_ten = 0;
        }
    }
}

class Demo
{
    public static void Main(string[] args)
    {
        TestClass tc = new TestClass();
        tc.ZeroToTen = 10;
        Console.WriteLine(tc.ZeroToTen);
    }
}
プロパティは原則として変数とセット(当然、ここのセットは set 設定の意味ではなく、一緒にという意味) で利用します。そもそもプロパティは前に述べたように、変数を利用する際の安全性を確保するものですから当然です。
そしてまた、プロパティ名は原則として大文字で指定します。そうしなければならないわけではありませんが、C# の言語仕様は大文字ですからそれに合わせることでわかりやすくなります。

実際のプロパティは以下の部分です。
public int ZeroToTen
アクセス修飾子・戻り値の型・プロパティ名という順はメソッドと変わりありません。

その中に先に述べた「get」「set」があります。
get ステートメントブロックは「取得」を意味しますから、値を返す「return」キーワードで変数の値を返しています。

set ステートメントブロックは「設定」です。ですからこの中に右辺の値が入った value が入っているはずです。
このステートメントで value が、すなわち代入しようとした値が 0 から 10 までかどうか判別し、そうであれば素直に value を代入し、そうでなければやむを得ず 0 を代入しています。

value なんて宣言してないぞ、なんて思わないように。value は常に右辺の値を意味しますから宣言する必要はありませんし、キーワードですから宣言できません。

目を下に移して、
tc.ZeroToTen = 10;
では get set のどちらが呼び出されるでしょうか。set ですよ。せってい → セッテイ → セット(set)、無理やりですがここで get が呼び出されると答えてはいけません。 0 = 10; になりますからエラーです。

Console.WriteLine(tc.ZeroToTen);
ここではどちらですか? get ですね。戻ってきた値は上で設定した値ですから「10」です。

このプログラムで 0 から 10 以外の値を代入しようとすると 0 になります。もちろん、代入するのはプロパティのようでその中で動いている変数に代入されます。
が、プロパティを変数のように見てもいいですが、このプログラムのようにいろいろな動作をさせることができます。

上のプログラムはメソッドで実装することも可能ですが、プロパティの方がはるかにスマートです。
プロパティは「変数とメソッドを足して2で割った」ようなものですから、複雑な動作をさせるのはメソッドに任せて、上のような設定・取得の際のちょっとした動作を実装します。

私自身はプロパティを宣言して使うことは余りしたことがありませんが、いろいろなプログラムを見る限り、きれいなプログラムは直接変数を利用するのではなく、プロパティを利用している場合が多いです。
もっと身近なところでは、.NET Framework でも this.text 変数などの代わりに this.Text プロパティを利用してゲット・セットしています。これなんかはただの文字列ですから変数でもよさそうな気もしますが、プロパティを利用しているよい例です。

[ ステップアップC# ] [ C#プログラミング応用講義 ]