.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>
読み取り専用にしない限り)。ただし、これが重要であるとはほとんど感じられません。