3

我正在设计一个具有多个返回对象列表的函数的类。我注意到,当 myIEnumerable<T>转换为 a时,调试变得更容易,List<T>因为可以在 Watch 窗口中查看对象。但是,我不确定这是否是IEnumerable.

问:哪个更好?

public IEnumerable<MyData> GetData()
{
    return Foo();
}

public IEnumerable<MyData> GetData()
{
    return Foo().ToList();
}
4

7 回答 7

5

良好做法 - 除非有充分的理由/要求,否则不要工作。因此,除非您有特殊原因 - 只需返回IEnumerable<MyData>而不调用 ToList()/ToArray() 即可。

潜在原因:

  • 函数承诺完成对潜在延迟枚举的评估
  • 您希望结果被枚举多次
于 2012-09-20T07:52:07.047 回答
2

更好地返回IEnumerable<..>为更通用的类型。调用者可以决定如何处理它。在您的情况下,您在两种情况下都返回IEnumerable<..>,因此没有任何理由run ToLIst(),只需返回IEnumerable

于 2012-09-20T07:49:51.663 回答
1

IEnumerable<T>正在为调用者提供一个 T 集合的合同。但是,当您使用IList<T>or时List<T>,您是在建议他们可以直接添加或删除元素(无需通过您在类实现中可能拥有的任何方法,例如 Add 或 Register)。如果您的意图只是让调用者看到“项目”,则 IEnumerable 是更好的合同。

虽然不是 100%,但我将 IEnumerable 返回值视为只读集合。

易于调试应该是良好设计的次要因素。我建议您简单地对您的类进行单元测试,而不是依赖于能够在运行时窥视内部。但是,在大多数情况下,调试器会将“基”类显示为第一项。所以 IEnumerable 的第一项是您在内部实际使用的列表。只需要再“展开”一次,就能看到成员!

于 2012-09-20T07:58:24.093 回答
1

这真的取决于你的要求。方法签名的返回类型也是该方法契约的一部分。返回 IEnumerable 的方法表示值流,而返回 List(或更抽象的 Collection)的方法返回值的可变集合。

我通常会尝试跟上以下做法。

  • 当没有关于值的数量的固定知识或加载所有值需要大量时间/资源(例如查询结果)时,尝试使用 IEnumerable 或 IObservable 流式传输数据。
  • 对预先知道的不可变的固定集合使用数组。
  • 将 ICollection 用于预先知道的可以变异的固定集合。
于 2012-09-20T07:51:07.867 回答
1

如果您正在使用将要处理的工作单元,我最好使用元素列表,因为一旦处理完毕,您将无法获得您的元素。

在所有其他情况下,可以返回通用IEnumerable,因为它提供了更好的灵活性。

最后,这一切都取决于您的要求,请注意 IEnumnerable 不会在分配给变量的确切时刻检索元素,而是在枚举时检索元素。

于 2012-09-20T07:51:52.330 回答
0

返回 IEnumerable 让调用者决定如何处理结果 - 要么枚举它,要么将它传递给其他东西而不在当前时刻枚举它。ToList() 强制此时将数据枚举到一个列表中,然后将其传递给调用者。

因此 - IEnumerable 很可能是两者中更好的 - 但是在调试时使用 ToList 会更容易。

于 2012-09-20T07:52:18.887 回答
0

有一个简单的规则:返回更具体,接受更通用。

如果您的返回值确实是IEnumerable<>,则按原样返回。但永远不要这样做:

public IEnumerable<MyData> GetData()
{
    return this.list; // list = new List<MyData>();
}

上面的代码在没有任何需要的情况下限制了调用者。例如,它将是一个列表,调用者无论如何都可以将其转换为列表并清除它。

于 2012-09-20T13:26:31.630 回答