【问题标题】:Why does this .Net Core implementation of ImmutableList<T> not produce an infinite loop?为什么这个 ImmutableList<T> 的 .Net Core 实现不会产生无限循环?
【发布时间】:2015-01-10 18:06:51
【问题描述】:

我一直在阅读 Microsoft 刚刚发布的 .Net 核心项目中的一些代码。 (https://github.com/Microsoft/dotnet) 很高兴能够看到 .Net 核心团队是如何实现的,我想我可以从他们的代码中学到一两件事。

引起我注意的一件事是 Clear() 的函数是如何实现的。

[SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly ImmutableList<T> Empty = new ImmutableList<T>();


public ImmutableList<T> Clear()
{
    Contract.Ensures(Contract.Result<ImmutableList<T>>() != null);
    Contract.Ensures(Contract.Result<ImmutableList<T>>().IsEmpty);
    return Empty;
}

在我看来,当您创建一个新列表时,空属性会填充一个新列表,然后在运行 Clear 函数时返回该列表;从而取消引用旧列表(如果你说:var students = students.Clear();)并允许 GC 清除旧列表。

所有这些都非常酷,我不明白的是,上面对 Empty 属性的定义如何不会导致无限循环?如果每次创建一个新列表时,它实际上会生成两个,那么这是否意味着为 Empty 属性列表实例化的新 ImmutableList 也为它的 Empty 属性实例化另一个等等?

有人可以解释一下吗?如果我上面的理解不正确,还请纠正我。

【问题讨论】:

  • 它是静态的 - 内存中只有一个 new ImmutableList&lt;T&gt; 用于此类型的 Empty 属性。
  • 您是否错过了静态关键字?
  • 谢谢@Charleh,我没有意识到静态是如何工作的。我认为它只是为那个实例在内存中创建了一个 new ImmutableList 。我很高兴我现在问了。

标签: c# .net infinite-loop immutablelist


【解决方案1】:

Empty 是静态的,因此只创建一次。由于它是不可变的,因此它向任何调用 Clear 的人返回相同的实例并不重要。

【讨论】:

  • 谢谢!我没有意识到静态是这样工作的。我以为每个实例只有一个,而不是所有实例,太棒了。如此简单但经过深思熟虑的代码。
  • 这只能安全地工作because a data race is irrelevant,因为会产生相同的数据。一般来说,static 不应被认为是线程安全的。
  • @Mgetz:静态字段初始化器是线程安全的。 .NET 运行时确保它们只运行一次。因此,仅仅因为数据竞赛无关紧要,这不是真的。没有数据竞争。
  • @Joren 正确,在这种情况下,数据竞争是不可能的,因为数据是不可变的,初始化没有问题。
猜你喜欢
  • 2011-12-08
  • 2021-12-19
  • 2013-03-29
  • 1970-01-01
  • 2018-03-17
  • 1970-01-01
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
相关资源
最近更新 更多