web-dev-qa-db-ja.com

クラスのプライベートメンバーでゲッターとセッターを使用するより良い方法はありますか?

私はこのサンプルクラスを持っています:

public class Carrots
{
    private string name;

    public void SetName(string pName)
    {
        name = pName;
    }

    public string GetName()
    {
        return name;
    }
}

クラスのメンバーをプライベートとして設定し、このメンバーを設定および取得するために、getおよびsetメソッドを作成しました。このコードを短くして一目で読みやすくする方法はありますか?

7
Gigabit

プロパティの使用

適切なゲッターとセッターは次のようになります。

public class Carrots
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

ここをクリック この例のキーワードvalueの役割を理解していない場合)。

自動プロパティの使用

C#3.0以降では、 auto-properties を使用してさらに簡単にすることもできます。

public class Carrots
{
    public string Name { get; set; }
}

パブリックプロパティを読み取り専用にする場合(ただし、プライベートセッターが必要な場合)は、以下を使用できます。

public class Carrots
{
    public string Name { get; private set; }
}

それを呼び出す方法

どちらの場合も、次のように呼び出します。

var c = new Carrots();
c.Name = "This is a test!";
Console.WriteLine(c.Name); //outputs "This is a test!"
10
John Wu

短くて読みやすいのは、次のようなものです。

public class Carrots
{
    public string Name { get; set; }
}

これは、プロパティにアクセスするときに使用される内部プライベート変数を使用します。に相当:

public class Carrots
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

(@John Wuが示したとおり)。

ただし、これは、外部コードからアクセスできるようにする内容によって異なります。

「名前」を即座に変更可能にしたいだけで、アプリケーションに影響がない場合は、上記のパブリック文字列Name {get;セットする; }で十分です。

ただし、クラス内のプロパティの値を追跡、使用、または制御していて、外部コードで値を変更したくない場合は、2番目の例が適しています。

たとえば:

既知の値で作成されたクラスがあります。その値を変更したいのですが、あなたの管理下にあります。

おそらく銀行残高?または車の速度?

車の速度で行きましょう:

public class Car
{
    private string _speed;

    public string Speed
    {
        get { return _speed; }
    // Notice no setter in this case.
    }

    public void IncreaseSpeed()
    {
        if(_speed + 1 <= 100)
        {
            _speed++;
        }
    }

    public void Brake()
    {
        if(_speed-- >= 0)
        {
            _speed--;
        }
    }
}

これにより、呼び出し元のコードは、必要に応じて何回でも速度を上げたり、ブレーキの保持を遅くしたりできます。しかし、その速度に現実的な制限を課すことができます。ユーザーは、アプリケーションの「世界」にあるルールを破ることはできません。

以下は別の例ですが、外部コードは値をすぐに設定できます。

public class Car
{
    private string _speed;

    public string Speed
    {
        get { return _speed; }
        set {
                if (value >= 0 && value <= 100)
                {
                    _speed = value;
                }
            }
    }
}

これにより、呼び出しコードが加速とブレーキを処理できるようになり、必要に応じてCarオブジェクトが更新されます。しかし、値の変更方法を制御するのではなく、その値が何であるかを全体的に制御できます。

使用:

public class Carrots
{
    public string name;
}

@Charles Merriamが示すように、外部コードがこのプロパティを設定するタイミングと値が気にならない場合は、すべて問題ありません。常に公開されており、変更されたときにチェックされません。

どのような状態にあるかについて境界が必要な場合、または特定の範囲が必要な場合は、クラスの内部メソッドからアクセスしないでください。無効なデータ入力を完全に防止するのではなく、境界チェックロジックにアクセスするすべての場所で境界チェックロジックを使用して(チェックが失敗した場合はエラーを処理する)必要があります。

1
Steve Padmore