1

私はこれが可能かどうか頭を包み込もうとしています。私の勘は、確認したかったのではないということです。

次の高階関数は、null合体演算子を使用します。

    public static Func<T> Coalesce<T>(this Func<T> source)
        where T : class
    {
        T local = default(T); 
        return delegate
        {
            return local ?? (local = source()); 
        }; 
    }

目標は、次のようにプロパティ内で使用することです。

    protected string SomeMember
    {
        get { return Coalesce(() => GetSomeMember())(); }
    }

意図したとおりに機能した場合、GetSomeMember()関数は、プロパティが最初に呼び出されたときに1回だけ呼び出されます。その後、プロパティの保存されたインスタンスを返すことができます。(その基本的なメモ化/ null合体の概念)。

ここで注意が必要なのは、プライベートフィールドの使用を選択する代わりに、格納されたインスタンスをクロージャー内にトラップしようとすることです。'SomeMember'の状態をSomeMemberを含むクラス内に保存できることは知っていますが、好奇心のためにそれを明示的に回避しようとしています。目標は、get {}ブロック内にとどまるために必要なすべてのものです(これには、Coalesce()から返されたデリゲートを格納しないことも含まれます)。

プロパティにアクセスするたびに、返される内部関数と外部関数の両方が呼び出されるため、問題が発生します。'T local'変数は毎回再割り当てされるため、null合体演算子は常にGetSomeMember()を再呼び出しします。

考え?

4

2 に答える 2

3

Coalesce()ゲッターを呼び出すたびに (あまりいい名前ではありませんが)呼び出しているため、このようには機能しません。デリゲートをフィールドに保存して使用できます。Lazy<T>ただし、それを行う場合は、フレームワークから使用する方がはるかに優れています。

private Lazy<string> m_someMember = new Lazy<string>(GetSomeMember);

protected string SomeMember
{
    get { return m_someMember.Value; }
}
于 2012-03-23T02:04:02.237 に答える
0

ゲッター内で取得しようとするクロージャーは、その呼び出しを過ぎて生き残ることができないため、可能ではないように見えます(オブジェクトに何も保存したくないため)。

于 2012-03-23T02:30:42.223 に答える