我想实现以下结构:
public interface IMyDbSet
{
IEnumerable<User> Users { get; }
}
public class ConcreteDbSet : IMyDbSet
{
DbSet<User> Users { get; set; }
}
虽然DbSet<T>
继承自IEnumerable<T>
,但这不可能。
Visual Studio错误消息:
....没有实现接口 会员'....'。 '......'无法实施 '....'因为它没有 匹配'....'的返回类型。
是否有另一种方法来实现这样的结构,或者这根本不可能?
感谢。
答案 0 :(得分:8)
最简单的方法是显式实现接口,并从显式Users
属性返回implicity Users
属性的值。
public interface IMyDbSet
{
IEnumerable<User> Users { get; }
}
public class ConcreteDbSet : IMyDbSet
{
IEnumerable<User> IMyDbSet.Users
{
get { return Users; }
}
DbSet<User> Users
{
get; set;
}
}
答案 1 :(得分:2)
这是不可能的,因为任何调用IMyDbSet.Users
的人都希望收到IEnumerable<User>
,这可能但不一定是DbSet<User>
。 DBSet<T>
为IEnumerable<T>
,但IEnumerable<T>
不是DbSet<T>
。
据说没有什么可以阻止您将DbSet<USer>
实例作为IEnumerable<User>
答案 2 :(得分:1)
您要使用的功能称为“return type covariance”,这在C#编程语言中是不合法的(不幸的是)。
在其他语言中,如C ++,Java或Eiffel(以及其他一些语言),您可以在覆盖虚拟方法或实现接口时使用更具体的类型。
如果您正在处理界面,您可以使用已知的习语(如Florian所提到的):您可以显式实现您的界面并添加另一个带有另一个签名的方法。
public interface IMyDbSet
{
IEnumerable<User> Users { get; }
}
public class ConcreteDbSet : IMyDbSet
{
IEnumerable<User> IMyDbSet.Users {get {return Users;}}
public DbSet<User> Users { get; set; }
}
另一个选项 - 用户通用IMyDbSet<T>
与来自bool Equals(object rhs)
的{{1}}和通用类型安全界面System.Object
类似:
[IEquatable<T>][2]