基本C#接口问题

基本C#接口问题,c#,inheritance,interface,C#,Inheritance,Interface,我想实现以下结构: public interface IMyDbSet { IEnumerable<User> Users { get; } } public class ConcreteDbSet : IMyDbSet { DbSet<User> Users { get; set; } } 公共接口IMyDbSet { IEnumerable用户{get;} } 公共类ConcreteDbSet:IMyDbSet { DbSet用户{get;set;

我想实现以下结构:

public interface IMyDbSet
{
    IEnumerable<User> Users { get; }
}

public class ConcreteDbSet : IMyDbSet
{
    DbSet<User> Users { get; set; }
}
公共接口IMyDbSet
{
IEnumerable用户{get;}
}
公共类ConcreteDbSet:IMyDbSet
{
DbSet用户{get;set;}
}
虽然
DbSet
继承自
IEnumerable
,但这是不可能的

Visual Studio错误消息:

。。。。不实现接口 成员“…”无法实施 因为它没有 匹配的返回类型为“..”

有没有其他方法来实现这样的结构,或者根本不可能


谢谢。

最简单的方法是显式实现接口,并从显式
用户
属性返回隐式
用户
属性的值

public interface IMyDbSet
{
    IEnumerable<User> Users { get; }
}

public class ConcreteDbSet : IMyDbSet
{
    IEnumerable<User> IMyDbSet.Users 
    {
        get { return Users; }
    }

    DbSet<User> Users 
    { 
        get; set; 
    }
}
公共接口IMyDbSet
{
IEnumerable用户{get;}
}
公共类ConcreteDbSet:IMyDbSet
{
IEnumerable IMyDbSet.Users
{
获取{返回用户;}
}
数据库集用户
{ 
获得;设置;
}
}

这是不可能的,因为无论谁调用
IMyDbSet.Users
都希望收到
IEnumerable
,这可能但不一定是
DbSet
DBSet
IEnumerable
,但
IEnumerable
不是
DBSet


话虽如此,但没有任何东西可以阻止您将
DbSet
实例作为
IEnumerable
返回,您要使用的特性称为“”,这在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; }
}

为什么要剪掉错误消息的重要部分?这正是问题所在。Cody Gray,错误应该是
ConcreteDbSet未实现接口成员IMyDbSet.Users。ConcreteDbSet.Users无法实现IMyDbSet.Users,因为它没有匹配的返回类型IEnumerable
@Cody:对不起,我没有先检查您的声誉。祝你过得愉快。
public interface IMyDbSet<T> where T : IEnumerable<User>
{
   // Because T is IEnumerable<User> or one of it descendant
   // this property is similar to IEnumerable<User> Users {get;}
   T Users {get;}
}

// Now we're implementing not IMyDbSet interface itself
// but we're IMyDbSet<IList<User>> instead.
// Note you could use your own descendant for IEnumerable<User> here
public class ConcreteDbSet : IMyDbSet<IList<User>>
{
    public IList<User> Users {get; set;}
}


//...
// and now you could use ConcreteDbSet following way:
var set = new ConcreteDbSet();
IList<User> users = set.Users;