在更高阶函数内使用null合并运算符

时间:2012-03-23 01:56:28

标签: c# lambda functional-programming closures higher-order-functions

我试图绕过这是否可能。我的预感是它不是,但想确认。

以下高阶函数使用空合并运算符:

    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()函数。此后,可以返回存储的属性实例。 (它的基本memoization / null合并概念)。

现在棘手的部分是尝试将存储的实例捕获到闭包中而不是选择使用私有字段。我知道你可以在包含SomeMember的类中存储'SomeMember'的状态,但我明确地试图为了好奇而避免这种情况。目标是将所有内容保留在get {}块中(包括存储从Coalesce()返回的委托)。

由于每次访问属性时都会调用内部返回函数和外部函数,因此存在问题。每次都会重新分配'T local'变量,因此空合并运算符总是重新调用GetSomeMember()。

思想?

2 个答案:

答案 0 :(得分:3)

它不会像这样工作,因为每次调用getter时你都会调用Coalesce()(不是一个好名字,BTW)。您可以将委托保存到字段并使用它。但是如果你这样做,那么从框架中使用Lazy<T>要好得多:

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

protected string SomeMember
{
    get { return m_someMember.Value; }
}

答案 1 :(得分:0)

看起来不可能,因为你试图进入内部的任何关闭getter将无法在该调用之后存活(因为你不想在对象上存储任何东西)。