gpt4 book ai didi

c# - 返回 Array 和 IList<> 有什么区别? (RE : Eric Lippert's harmful arrays)

转载 作者:行者123 更新时间:2023-11-30 13:36:27 25 4
gpt4 key购买 nike

我刚刚读了Eric Lippert's "Arrays considered somewhat harmful"文章。他告诉他的读者,他们“可能不应该返回一个数组作为公共(public)方法或属性的值”,推理如下(略有释义):

Now the caller can take that array and replace the contents of it with whatever they please. The sensible thing to return is IList<>. You can build yourself a nice read-only collection object once, and then just pass out references to it as much as you want.

本质上,

An array is a collection of variables. The caller doesn’t want variables, but it’ll take them if that’s the only way to get the values. But neither the callee nor the caller wants those variables to ever vary.

为了理解他所说的变量与值的含义,我构建了具有 Array 的演示类和 IList<>字段和返回对两者的引用的方法。 Here it is on C# Pad.

class A {

private readonly int[] arr = new []
{
10, 20, 30, 40, 50
};

private readonly List<int> list = new List<int>(new []
{
10, 20, 30, 40, 50
});

public int[] GetArr()
{
return arr;
}

public IList<int> GetList()
{
return list;
}
}

如果我没理解错的话,GetArr()方法是 Lippert 的坏习惯,并且 GetList()是他明智的做法。这是 GetArr() 的不良调用者可变性行为的演示。 :

var a = new A();
var arr1 = a.GetArr();
var arr2 = a.GetArr();

Console.WriteLine("arr1[2]: " + arr1[2].ToString()); // > arr1[2]: 30
Console.WriteLine("arr2[2]: " + arr2[2].ToString()); // > arr2[2]: 30

// ONE CALLER MUTATES
arr1[2] = 99;

// BOTH CALLERS AFFECTED
Console.WriteLine("arr1[2]: " + arr1[2].ToString()); // > arr1[2]: 99
Console.WriteLine("arr2[2]: " + arr2[2].ToString()); // > arr2[2]: 99

但我不明白他的区别-IList<>引用有相同的调用者突变问题:

var a = new A();
var list1 = a.GetList();
var list2 = a.GetList();

Console.WriteLine("list1[2]: " + list1[2].ToString()); // > list1[2]: 30
Console.WriteLine("list2[2]: " + list2[2].ToString()); // > list2[2]: 30

// ONE CALLER MUTATES
list1[2] = 99;

// BOTH CALLERS AFFECTED
Console.WriteLine("list1[2]: " + list1[2].ToString()); // > list1[2]: 99
Console.WriteLine("list2[2]: " + list2[2].ToString()); // > list2[2]: 99

显然,我相信 Eric Lippert 知道他在说什么,那么我在哪里误解了他? IList<>以什么方式返回引用比 Array 更安全引用?

最佳答案

如果那篇文章是今天写的,它几乎肯定会建议使用 IReadOnlyList<T> ,但在 2008 年撰写该文章时,该类型并不存在。具有只读可索引列表接口(interface)的唯一受支持方法是使用 IList<T>并且根本不执行变异操作。这确实让您返回一个调用者不能改变的对象,尽管不一定清楚(特别是从 API 来看)该对象实际上是不可变的。从那时起,.NET 中的这个缺点就得到了补救。

关于c# - 返回 Array 和 IList<> 有什么区别? (RE : Eric Lippert's harmful arrays),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33529305/

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