【问题标题】:Is there a void version of Lazy<T>?是否有 Lazy<T> 的无效版本?
【发布时间】:2014-03-17 14:32:06
【问题描述】:

我想在课堂上使用Lazy&lt;T&gt; 的行为来确保某个操作只发生一次。我之前通过有一个 Lazy 来做到这一点,它本质上调用了一个 Func 来做某事,然后返回一个空值。我不关心返回值,我只想确保事情只发生一次。

我想它可以称为Once。如果它尚不存在,我将自己构建并在内部使用Lazy,但我想在这样做之前先问一下。谢谢!

【问题讨论】:

  • 我很好奇其中的原因。因为你对返回值不感兴趣,为什么要多次调用这个“函数”却只希望它执行一次?
  • 除非我遗漏了什么,否则你不能直接使用singleton pattern吗?
  • 有一些初始化逻辑我通常只会在构造函数中调用,但我更愿意避免在构造函数中调用我的依赖项,因为这可能会在使用 DI 时导致问题。
  • 相反,我想将此初始化推迟到第一次调用其中一个方法。为此使用 Lazy 很容易,只是想知道是否有办法不浪费 T。:)

标签: .net lazy-initialization


【解决方案1】:

它还不存在。使用Lazy&lt;object&gt; 并从工厂返回null

您可以像您说的那样将其封装到 Once 类中,但不要从 Lazy&lt;object&gt; 继承,因为这会滥用继承。使用适当的封装。

您也可以使用 LazyInitializer 类,这取决于个人喜好。

【讨论】:

  • 谢谢。绝对不会为此使用继承。我只会在Once 上有一个Lazy&lt;object&gt; 字段。
【解决方案2】:

如果您不需要绝对控制何时初始化发生,您可以使用其中一个类的静态构造函数。否则,您可以使用以下内容:

您可以使用Lazy&lt;T&gt;LazyInitializer。这是后者的一个例子。

private object _initializationObject;

// this is used to ensure the initialization function only runs once, even in
// multi-threaded scenarios
private bool _initialized;
private readonly object _initializationLock = new object();

private void Initialize()
{
  // run the initialization once
  LazyInitializer.EnsureInitialized(
    ref _initializationObject, ref _initialized,
    _initializationLock, InitializeImpl);
}

private object InitializeImpl()
{
  // initialization code...

  return null;
}

【讨论】:

  • 爱它。然而,它最终是太多的代码,它仍然有一个像Lazy&lt;T&gt; 这样的通用要求,而我没有这样的要求。
【解决方案3】:

如前所述,是实现您想要的好主意

1) 使用 Lazy&lt;object&gt; 返回 null..
2) 使用 LazyInitializer.EnsureInitialized&lt;T&gt; 也返回 null ..
3) 使用单例模式或类似的东西...

但我推荐另一种方法

使用任务初始化,您可以在此处查看更多详细信息: http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html

基本思想是创建一个任务,不需要异步执行,只需要等待它完成,如果完成了,直接执行该方法。

所有方法都非常相似,请随意选择适合您解决方案的方法。

【讨论】:

  • 谢谢。在我看来,Tasks 似乎有点过分了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
相关资源
最近更新 更多