gpt4 book ai didi

c# - IEnumerable 与数组

转载 作者:IT王子 更新时间:2023-10-29 04:24:34 24 4
gpt4 key购买 nike

我想弄明白,将对象的只读列表发布为公共(public)方法的最佳方式是什么?来自 Eric Lippert's Blog ,数组有点糟糕,因为有人可以轻松添加新条目。因此,每次调用该方法时都必须传递一个新数组。他建议,通过 IEnumerable<T> ,因为这是只读定义(没有添加、删除方法),我已经练习了很长时间。但在我们的新项目中,人们甚至开始创建这些 IEnumerables 的数组,因为他们不知道背后的数据源,所以他们得到一个:Handling warning for possible multiple enumeration of IEnumerable

我对一种技术方法很感兴趣,即如何解决这个难题。到目前为止我想出的唯一解决方案是使用 IReadOnlyCollection , 但这比 IEnumerable 更明确.

发布此类列表的最佳做法是什么,这些列表不应更改,但应声明为内存中列表?

最佳答案

通常 - 并且有一段时间 - 使用 immutable collections 解决了这个问题.

例如,您的公共(public)属性应该属于 IImmutableList<T> 类型, IImmutableHashSet<T>等等。

任何IEnumerable<T>可以转换为不可变集合:

  • someEnumerable.ToImmutableList();
  • someEnumerable.ToImmutableHashSet();
  • ... 等等

通过这种方式,您可以使用可变集合处理私有(private)属性,并仅提供不可变集合的公共(public)表面。

例如:

public class A
{
private List<string> StringListInternal { get; set; } = new List<string>();
public IImmutableList<string> StringList => StringListInternal.ToImmutableList();
}

还有一种使用接口(interface)的替代方法:

public interface IReadOnlyA
{
IImmutableList<string> StringList { get; }
}

public class A : IReadOnlyA
{
public List<string> StringList { get; set; } = new List<string>();
IImmutableList<string> IReadOnlyA.StringList => StringList.ToImmutableList();
}

检查 IReadOnlyA has been explicitly-implemented ,因此既可变又不可变StringList属性可以作为同一类的一部分共存。

当你想公开一个不可变的 A 时, 然后你返回你的 A对象向上转换为 IReadOnlyA上层将无法改变整个 StringList在上面的示例中:

public IReadOnlyA DoStuff()
{
return new A();
}

IReadOnlyA a = DoStuff();

// OK! IReadOnly.StringList is IImmutableList<string>
IImmutableList<string> stringList = a.StringList;

避免每次都将可变列表转换为不可变列表

这应该是一种可能的解决方案,以避免每次访问不可变列表时都将源列表转换为不可变列表。

平等成员

如果项目类型覆盖 Object.EqualsGetHashCode ,并可选择实现 IEquatable<T> ,那么公共(public)不可变列表属性访问可能如下所示:

public class A : IReadOnlyA
{
private IImmutableList<string> _immutableStringList;

public List<string> StringList { get; set; } = new List<string>();

IImmutableList<string> IReadOnlyA.StringList
{
get
{
// An intersection will verify that the entire immutable list
// contains the exact same elements and count of mutable list
if(_immutableStringList.Intersect(StringList).Count == StringList.Count)
return _immutableStringList;
else
{
// the intersection demonstrated that mutable and
// immutable list have different counts, thus, a new
// immutable list must be created again
_immutableStringList = StringList.ToImmutableList();

return _immutableStringList;
}
}
}
}

关于c# - IEnumerable<T> 与数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33859562/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com