基本的C#接口问题

时间:2011-05-10 09:53:04

标签: c# inheritance interface

我想实现以下结构:

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

public class ConcreteDbSet : IMyDbSet
{
    DbSet<User> Users { get; set; }
}

虽然DbSet<T>继承自IEnumerable<T>,但这不可能。

Visual Studio错误消息:

  

....没有实现接口   会员'....'。 '......'无法实施   '....'因为它没有   匹配'....'的返回类型。

是否有另一种方法来实现这样的结构,或者这根本不可能?

感谢。

3 个答案:

答案 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]