1

我正试图围绕这是否可能。我的直觉是,它不是但想确认。在高阶函数中使用空合并运算符

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

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

你不只是试图封装一个懒惰的实例吗? – 2012-03-23 01:58:57

+0

不,重点是通常是一个私人领域,而不是一个封闭的变量。 – 2012-03-23 03:00:56

+0

@SeanThoman,闭包总是与某个委托(或'Expression')关联。如果你想创建一次闭包,然后重复使用它,这意味着你需要将委托存储在某个地方,可能在一个字段中。 – svick 2012-03-23 12:32:30

回答

3

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

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

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

看起来并不可能,因为无论封你会尝试里面的getter得到将无法过去那种呼叫生存(如你不想在对象上存储任何东西)。