キャッシュされたプロパティと遅延 質問する

キャッシュされたプロパティと遅延 質問する

.NET 4では、キャッシュされたプロパティを持つ次のスニペットも、System.Lazy<T>クラス。両方のアプローチのパフォーマンスを測定したところ、ほぼ同じでした。どちらか一方を使用するべき理由として、実際の利点や魔法があるのでしょうか?

キャッシュされたプロパティ

public static class Brushes
{
    private static LinearGradientBrush _myBrush;

    public static LinearGradientBrush MyBrush
    {
        get
        {
            if (_myBrush == null)
            {
                var linearGradientBrush = new LinearGradientBrush { ...};
                linearGradientBrush.GradientStops.Add( ... );
                linearGradientBrush.GradientStops.Add( ... );

                _myBrush = linearGradientBrush;
            }

            return _myBrush;
        }
    }
}

怠け者<T>

public static class Brushes
{
    private static readonly Lazy<LinearGradientBrush> _myBrush =
        new Lazy<LinearGradientBrush>(() =>
            {
                var linearGradientBrush = new LinearGradientBrush { ...};
                linearGradientBrush.GradientStops.Add( ... );
                linearGradientBrush.GradientStops.Add( ... );

                return linearGradientBrush;
            }
        );

    public static LinearGradientBrush MyBrush
    {
        get { return _myBrush.Value; }
    }
}

ベストアンサー1

一般的には以下を使用しますLazy<T>:

  • スレッドセーフです(この場合は問題にならないかもしれませんが、他の場合には問題になることがあります)
  • 名前だけで何が起こっているのか一目瞭然だ
  • nullを有効な値として許可する

注意:持っているデリゲートにラムダ式を使用します。たとえば、もう少し簡潔なアプローチを次に示します。

public static class Brushes
{
    private static readonly Lazy<LinearGradientBrush> _myBrush =
        new Lazy<LinearGradientBrush>(CreateMyBrush);

    private static LinearGradientBrush CreateMyBrush()
    {
        var linearGradientBrush = new LinearGradientBrush { ...};
        linearGradientBrush.GradientStops.Add( ... );
        linearGradientBrush.GradientStops.Add( ... );

        return linearGradientBrush;
    }

    public static LinearGradientBrush MyBrush
    {
        get { return _myBrush.Value; }
    }
}

GradientStopsこれは、ループなどで作成プロセスが複雑になった場合に特に便利です。作成コードでコレクション初期化子を使用できることに注意してください。

もう一つの選択肢はないもちろん、これを遅延実行します...クラス内にそのようなプロパティが複数あり、関連するオブジェクトを 1 つずつ作成するだけの場合を除いて、多くの状況で遅延クラス初期化に頼ることができます。

DoubleDown の回答に記載されているように、これをリセットして再計算を強制する方法はありません (フィールドをLazy<T>読み取り専用にしない限り)。ただし、これが重要であるとはほとんど感じられません。

おすすめ記事