2 回答
TA贡献1827条经验 获得超7个赞
我想你可能对这个有一个小小的误解IEnumerable
。它只是说该类支持迭代。它不会直接影响数据的获取方式。
此外,IQueryable
实现IEnumerable
,因此所有IQueryable
实例也是IEnumerable
。这是有道理的,因为您可以迭代结果。
在您的示例中,缺少这意味着IQueryable
“从数据库检索所有行,然后在 C# 中进行过滤”。
TA贡献1946条经验 获得超4个赞
LINQ 中有 2 个不同的扩展 - IEnumerable和IQueryable。
当您编写EntityRepository<Attachment>().Entities
.Where(at => at.EntityType == EntityType.EmailTemplate)
编译器时,它会检查类型Entities
,并声明“更具体”,IQueryable
编译器会选择Queryable.Where()
方法,并且表达式由IQueryProvider转换为 SQL。当您编写时,.ToDictionary(at => at.Extension, at => at)
编译器找不到Queryable.ToDictionary()
,因此它会回退到Enumerable.ToDictionary()
内存中过滤项目。
C# 语言规范中定义了扩展方法调用规则:
候选方法集被简化为仅包含来自最派生类型的
C.F
方法:对于集合中的每个方法,其中C
是声明该方法的类型F
,所有在 的基类型中声明的方法都C
将从集合中删除。此外,如果C
是 以外的类类型object
,则接口类型中声明的所有方法都将从集合中删除。(后一条规则仅在方法组是对具有除 object 之外的有效基类和非空有效接口集的类型参数进行成员查找的结果时才有效。)
public interface IInterfaceA { }
public interface IInterfaceB : IInterfaceA { }
public static class MyExtensions {
public static void Print(this IInterfaceA a) => Console.WriteLine("A");
public static void Print(this IInterfaceB b) => Console.WriteLine("B");
}
public class AB: IInterfaceA, IInterfaceB { }
public class BA: IInterfaceB, IInterfaceA { }
public partial class Program
{
static void Main(string[] args)
{
new AB().Print(); // B
new BA().Print(); // B
}
}
- 2 回答
- 0 关注
- 107 浏览
添加回答
举报