0

只是我在维护一个项目。它是用 C# 3.0 编写的。一些实现将集合返回为 IQueryable。

喜欢

List<BookData> data = new List<BookData>();
   ...

   data.Add(new BookData { ID = "P001", BookTitle = "C# in Depth" });
   data.Add(new BookData { ID = "P002", BookTitle = "F# in Depth" });

    public IQueryable GetBooks()
    {
        return data.AsQueryable();
    }

该代码将返回集合列表。将它们返回为 AsQueryable 有什么特别之处?

4

2 回答 2

0

如果不使用反射或强制转换返回的对象,返回集合上唯一可用的方法是接口定义的方法。这将是限制对集合的某些类型的访问的一种方式——例如,IQueryable 没有 add 方法。不幸的是,面对您的代码的“敌对”用户,这并不安全。如果您确实需要集合不可侵犯,更好的方法是返回集合的只读副本,而不是将实际的集合转换为不同的接口。

请注意,我假设一个列表(如您的示例中所示),或者其他一些实际在本机实现 IQueryable 的类。在这种情况下,源对象被返回。如果底层对象没有实现 IQueryable,则返回一个 IQueryable,它代理对底层 IEnumerable 的调用。

于 2009-12-20T20:25:32.193 回答
0

AsQueryable 在像 a 这样的普通旧集合上调用时实际上并没有做任何事情List<T>,因此答案可能取决于代码库的另一部分。例如,某人可能已经定义了一个 GetBooks 方法来获取IQueryable<Book>,其意图是 GetBooks 方法将通过 LINQ 提供程序在数据库中执行任何排序或过滤。但是您正在查看的代码将书集构造为集合 (a List<Book>),而不是查询。为了将结果传递给假设的 GetBooks 方法,必须将集合包装在一个 中IQueryable<Book>,即使该包装器只是将直接委托回 LINQ to Objects 方法(而不是将 GetBooks 操作转换为 SQL 查询) .

或者您正在查看的类可能实现了一个接口,其中您正在查看的方法被声明为返回IQueryable<Book>(出于与上述类似的原因),因此您的代码必须包装List<Book>以保持与接口签名兼容。

于 2009-12-20T20:26:10.437 回答