之间有什么区别
public IDbSet<Chrip> Chirps { get; set; }
和
public DbSet<Chrip> Chirps { get; set; }
他们是一样的吗?
答案 0 :(得分:16)
Sam I am's answer巧妙地定义了接口和类之间的区别,但在选择要在代码中使用的内容时还有其他注意事项。
具体来说 - 一个类可以实现多个接口,或者可以实现任何接口未定义的方法和属性。
在这种情况下,IDbSet<TEntity>
接口定义大多数 DbSet<TEntity>
类使用的方法和属性,但不是全部。例如,FindAsync
,RemoveRange
和SqlQuery
方法仅存在于具体的类实现中。如果在代码中使用该接口,则在没有首先转换为具体类型的情况下,您将无法使用这些特定方法。
此外,the Remarks section in the MSDN for IDbSet<TEntity>
还有一个有趣的观点:
IDbSet<TEntity>
最初旨在允许为DbSet<TEntity>
创建测试双打(模拟或假货)。但是,这种方法存在的问题是,在接口中添加新成员会破坏已经实现接口而没有新成员的现有代码。因此,从EF6开始,不会向此接口添加新成员,建议将DbSet<TEntity>
用作测试双精度的基类。
我认为扩展这种思路可以安全地说你通常应该使用DbSet<TEntity>
而不是IDbSet<TEntity>
声明你的属性,除非你有充分的理由不这样做。
答案 1 :(得分:2)
通常,当类型名称以I
开头时,它是一个接口。这不是一个硬规则,而只是一个命名约定。
DbSet
可能会实现IDbSet
假设您有这样的界面
public interface IFoo
{
int Echo(int bar);
}
一个类会实现像这样的接口
public class Foo : IFoo
{
public int Echo(int bar)
{
return bar;
}
}
这意味着您的类Foo
必须实现接口所说的每个方法,在这种情况下,这是一个名为Echo
的方法,它以int
作为输入,并且返回int
。
这允许你做的是以相同的方式对待一堆不同的类,即使你不知道它们是如何实现的。有关详细信息,请参阅Polymorphism。