3

次のスニペットは、私が最近よく遭遇する質問を示しています。

基本的に、示されているように継承を使用するよりも、プロパティのバッキング値を非表示にするためのより良い解決策があるかどうかを知りたいです。

副次的な質問として、私の非コンパイル ソリューションによって暗示された機能は、C# の将来のバージョンに役立つものでしょうか?

// This is a service that supplies a value but doesn't want to be called 
// until needed.
static class Service
{
    public static int GetP()
    {
        Console.WriteLine ("doing work...");
        return 1;
    }
}

// This is a class that implements a property which calls the service
// the first time that property is accessed but nothing stops the
// same code from accidentally referencing the uninitialized backing value.
class C
{
    void F()
    {
        // Easy to accidentally reference backing value of property
        Console.WriteLine (this.p);
    }

    int p = 0;
    int P
    {
        get
        {
            if(p == 0)
                p = Service.GetP();
            return p;
        }
    }
}

プライベートバッキング値を持つ継承と保護されたプロパティを使用したソリューション。

// This class hides the backing value and exposed the property the derived class.
class CBase
{
    int p = 0;
    protected int P
    {
        get
        {
            if(p == 0)
                p = Service.GetP();
            return p;
        }
    }
}

class C1 : CBase
{
    void F()
    {
        // Now I can't see the backing value but I've used inheritance for the sole purpose of hiding it
        Console.WriteLine (this.P);
    }
}

最初の実行時使用まで設定を遅らせるインスタンス レベルのメソッド/プロパティの本体に const がある場合はどうでしょうか?

class D
{
    int P
    {
        get
        {
            const int a = Service.GetP(); // Doesn't compile
            return a;
        }
    }
}
4

1 に答える 1

3

.net 4を使用している場合は、Lazyクラスを使用してください。

class C
{
    private Lazy<int> p = new Lazy<int>(() => Service.GetP());

    private int P
    {
        get
        {
            return p.Value;
        }
    }
}

Lazy.Valueに初めてアクセスすると、コンストラクターに提供された関数が呼び出され、値が初期化されます。

于 2012-09-07T22:14:02.043 に答える