使用 lambda 进行延迟字段初始化 [英] Lazy field initialization with lambdas

查看:23
本文介绍了使用 lambda 进行延迟字段初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在没有 if 语句的情况下实现延迟字段初始化(或延迟初始化)并利用 lambdas.因此,我希望具有以下 Foo 属性的相同行为,但没有 if:

I would like to implement lazy field initialization (or deferred initialization) without an if statement and taking advantage of lambdas. So, I would like to have the same behavior of the following Foo property but without the if:

class A<T>{
    private T fooField;

    public T getFoo(){
        if( fooField == null ) fooField = expensiveInit();
        return fooField;
    }
}

忽略这个解决方案不能保证安全使用的事实:1)多线程;2) null 作为 T 的有效值.

Ignore the fact that this solution is not guaranteeing safe use for: 1) multi-threading; 2) null as a valid value of T.

因此,为了表达将 fooField 的初始化推迟到其第一次使用时的意图,我想声明 Supplier< 类型的 fooFieldT> 如:

So, to express the intention that the initialization of the fooField is deferred until its first use I would like to declare the fooField of the type Supplier<T> such as:

class A<T>{
   private Supplier<T> fooField = () -> expensiveInit();

   public T getFoo(){
      return fooField.get();
   }
}

然后在 getFoo 属性中,我将只返回 fooField.get().但是现在我希望对 getFoo 属性的下一次调用避免 expensiveInit() 并只返回前一个 T 实例.

and then in the getFoo property I would just return fooField.get(). But now I want that next invocations to getFoo property avoid the expensiveInit() and just return the previous T instance.

如何在不使用 if 的情况下实现这一点?

How can I achieve that without using an if?

尽管有命名约定并将 -> 替换为 =>,那么在 C# 中也可以考虑这个示例.但是,NET Framework 版本 4 已经提供了具有所需语义的 Lazy.

Despite naming conventions and replacing the ->by =>, then this example could be also considered in C#. However, NET Framework version 4 already provides a Lazy<T> with the desired semantics.

推荐答案

在您的实际 lambda 中,您可以简单地使用新的 lambda 更新 fooField,例如:

Within your actual lambda, you can simply update the fooField with a new lambda, such as:

class A<T>{
    private Supplier<T> fooField = () -> {
       T val = expensiveInit();
       fooField = () -> val;
       return val;
    };

    public T getFoo(){
       return fooField.get();
    }
}

同样,这个解决方案不像 .Net Lazy 那样是线程安全的,并且不能确保对 getFoo 属性的并发调用返回相同的结果.

Again this solution is not thread-safe as is the .Net Lazy<T>, and does not ensure that concurrent calls to the getFoo property return the same result.

这篇关于使用 lambda 进行延迟字段初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆