代码之家  ›  专栏  ›  技术社区  ›  evilsushi

C#接口不允许成员类满足要求

  •  2
  • evilsushi  · 技术社区  · 6 年前

    抱歉,如果标题不是很有描述性。我不知道该怎么形容这个。

    首先,我创建了如下界面:

    public interface IUser {}
    

    然后在几个类中实现它,如下所示:

    public class Student : IUser {}
    
    public class Teacher : IUser {}
    

    然后我创建了一个需要第一个接口的接口

    public class IUsers
    {
        List<IUser> Users {get; set;}
    }
    

    然后,我创建了一个使用第二个接口的类,但使用第一个接口的一个成员来填充合同。

    public class Students : IUsers 
    {
        List<Student> Users {get; set;}
    }
    

    这个问题是我想将列表限制为接口的一个实现的最后一个问题,但仍然需要维护接口以实现数据兼容性。当我这样做时,我得到一个错误,说我没有实现接口。我原以为,既然学生实现了这个接口,它就可以填补这个义务,但似乎没有。这是对的还是我做错了什么

    2 回复  |  直到 6 年前
        1
  •  8
  •   Jon Skeet    6 年前

    你需要说什么 友善的 集合支持的用户数。假设您的代码是有效的-那么这将编译:

    IUsers users = new Students();
    // What would this do at execution time? It's not safe!
    users.Users.Add(new Teacher());
    

    毕竟,这只是增加了 Teacher 到a List<IUser> 正当但在 Students 这个 Users 属性是 List<Student> ,所以不能接受老师。

    最好的方法可能是 IUsers 它接受的用户类型的通用接口:

    public class IUsers<TUser> where TUser : IUser
    {
        List<TUser> Users {get; set;}
    }
    

    然后你的 学生 类将实现 IUsers<Student> ,财产就可以了。

    此时,答案顶部的问题示例将无法编译:

    // This is fine
    IUsers<Student> users = new Students();
    // This won't compile, because users.Users is of type List<Student>, and you can't add
    // a Teacher to that.
    users.Users.Add(new Teacher());
    
        2
  •  1
  •   Greg    6 年前

    根据代码,在我看来,示例表明您希望为用户维护单独的实现,然后返回所需的实现。

    public interface IStudentFactory
    {
         IUser Create();
    }
    
    public class StudentFactory
    {
        public IUser Create() => new StudentContext();
    }
    

    然后,根据您在IUser界面内的实现,您可以连接到数据存储来管理这些类型的用户。

    var context = new StudentFactory().Create())
    var students = context.GetAllStudents();
    context.Students.Add(new Student() { }); 
    

    我提供的方法的概念是,您希望能够访问有关不同类型用户的信息、持久化和管理。您的示例显示了您正在添加的一个基本集合,可能会处理其他功能,但我认为您正在朝着更加一致的方向努力。

    我可能与你的意图不符,但这就是我的解释。