Galileo Figaro

常に初陣!

プロパティでやることの例

プロパティの役割

下記の記事でも述べたように、 プロパティは、インスタンス内部に持っているデータを、 外部から取得・設定する Getter/Setter の役割を持っています。

gero-blog.hatenablog.com

上記の記事では、インスタンス内部のデータを、 単に取得したり設定したりするような Getter/Setter を 書きました。 ここでは、初学者向けに、もうちょっと実用的な Getter/Setter の例を紹介します。

必ず対応したフィールドがあるわけではない

冒頭のリンク先の記事では、 インスタンス内部の age というフィールドの値を、 Age というプロパティを通して取得・設定していました。 フィールドとプロパティが一対一に対応付いているような 作りになっていましたが、一般的なプロパティは、 必ずしも対応付いているわけではないです。 次の例を見てみましょう。

public string FirstName { get; }

public string FamilyName { get; }

public string FullName
{
    get
    {
        return FirstName + " " + FamilyName;
    }
}

この例では 3 つのプロパティがありますが、 FullName プロパティは、他のプロパティから作り出されています。 一方、このクラスの利用者からみると、あたかも FirstNameFamilyNameFullName という 3 つのデータを持っているように見えます。

また、次の例を見てみましょう。

public int MaxMemberCount
{
    get
    {
        return 999;
    }
}

この例では、フィールドも何も存在せず、 ただ「999」という固定値を返しているだけです。

このように、インスタンスが持っている複数のデータから 一つのプロパティ値を構成したり、 逆に、インスタンス内のデータを使わず固定値を返したりする 場合があります。

Setter での値の検証

Setter では、セットされてきた値が受け入れ可能かどうか、 チェックするということがよく行われます。 例えば次のコードでは、名前が空白の場合は 受け入れないようにしています。

private string _name;
public string Name
{
    get => _name;
    set
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException("名前がnullまたは空文字のみで構成されています。");
        }
        _name = value;
    }
}

おそらくこのクラスには、この Name を使用する処理があり、 きっと名前が空文字だけだとマズイ処理があるのでしょう。 空白をトリムして使うとしたら、文字列長は 0 になってしまうので、 そうなると何らかのバグを引き起こしちゃうことにもなりかねません。

このように、変な値を受け入れると、クラス内部のロジックが破綻してしまう ことがよくあるので、変な値は受け入れず、Setter で弾くようにしましょう。