首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在API中返回的最佳集合类型是什么

在API中返回的最佳集合类型是什么
EN

Stack Overflow用户
提问于 2010-06-28 11:22:03
回答 4查看 2.5K关注 0票数 12

我一直认为,当有一个公共API时,返回数组比列表更好,但现在似乎可以通过LINQ等在列表上使用所有这些函数。

这里是否更改了返回原语或对象集合的最佳实践?

例如:

代码语言:javascript
运行
复制
Order[] GetOrders();
List<Order> GetOrders();
IEnumerable<Order> GetOrders();
IQueryable<Order> Get Orders();
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-06-28 11:34:12

我认为最常用的类型是IEnumerable<T>

具有IEnumerable<T>返回类型的

  • 您可以使用yield关键字,这样就可以延迟枚举和执行您的方法。(例如,一个常见的抱怨是System.IO.Path.GetFiles()不返回数组,而是返回一个数组,这意味着当您调用该方法时,需要枚举所有项,而不管您是否需要它们。+你也有同样的缺点,在IEnumerable<T>
  • The IEnumerable<T>返回类型上工作的List<T>)
  • Most LINQ扩展方法不会假设任何关于调用者的具体信息。如果调用者需要列表或数组,他们总是可以创建由List<T>Array实现的one.
  • IEnumerable<T>,因此很容易更改方法的实现,并且仍然支持以前的返回类型。
票数 5
EN

Stack Overflow用户

发布于 2010-06-28 11:47:32

因为我通常只从属性/方法返回不可变(不可修改)的对象,所以这个答案假设您也想这样做。

不要忘记ReadOnlyCollection<T>,它返回一个仍然可以通过索引访问的不可变集合。

如果您正在使用IEnumerable<T>并将您的类型发布到无法控制的荒野中,请注意这一点:

代码语言:javascript
运行
复制
class MyClass {
    private List<int> _list;
    public IEnumerable<int> Numbers {
        get { return _list; }
    }
}

因为用户可能会这样做,并弄乱类的内部状态:

代码语言:javascript
运行
复制
var list = (List<int>)myClass.Numbers;
list.Add(123);

这将违反属性的只读意图。在这种情况下,你的getter应该是这样的:

代码语言:javascript
运行
复制
    public IEnumerable<int> Numbers {
        get { return new ReadOnlyCollection<int>(_list); }
    }

或者,您可以调用_list.ToReadOnly()。我把它完整地写出来,以显示它的类型。

这将阻止任何人修改您的状态(除非他们使用反射,但这真的很难阻止,除非您构建像许多函数式编程语言中使用的那样的不可变集合,而这完全是另一回事)。

如果要返回只读集合,最好将成员声明为ReadOnlyCollection<T>,这样某些操作的执行速度会更快(获取计数,通过索引访问项,复制到另一个集合)。

就我个人而言,我希望看到框架包含并使用这样的接口:

代码语言:javascript
运行
复制
public interface IReadOnlyCollection<T> : IEnumerable<T>
{
    T this[int index] { get; }
    int Count { get; }
    bool Contains(T item);
    void CopyTo(T[] array, int arrayIndex);
    int IndexOf(T item);
}

您可以在IEnumerable<T>之上使用扩展方法获得所有这些函数,但它们的性能不是很好。

票数 7
EN

Stack Overflow用户

发布于 2010-06-28 11:34:39

是否希望集合是不可变的?IEnumerable<T>可变的?IList<T>

你需要索引吗?IList<T>

通过列表或数组,API使用者拥有添加、删除、删除、清除等全部功能。

使用IEnumerable<T>,API使用者得到一个“包”中的项,没有特定的顺序,没有索引,也没有修改集合的方法。

在某些有限的情况下,您可能希望返回IQueryable<T>,但这些情况通常特定于零散地构建查询。

一般来说,我会默认使用IEnumerable<T>。我可能会使用List<T>作为支持字段,但只希望允许用户删除,例如,不允许删除、清除或其他任何操作,所以我声明了一个public void Add<T>(T item),它只是将该项添加到支持字段列表中。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3129889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档