C# 在c语言中的每个派生类中都有一个更具体的接口#

C# 在c语言中的每个派生类中都有一个更具体的接口#,c#,inheritance,interface,member-hiding,C#,Inheritance,Interface,Member Hiding,我试图给出一个尽可能简单的例子,但问题的本质至少让我感到困惑 为了重用代码而不重复我自己,我有一个接口IStudent,它实现了另一个接口IPerson interface IPerson { string FirstName { get; set; } string LastName { get; set; } } interface IStudent : IPerson { int StudentNumber { get; set; } } 我有一个类实现了ISt

我试图给出一个尽可能简单的例子,但问题的本质至少让我感到困惑

为了重用代码而不重复我自己,我有一个接口
IStudent
,它实现了另一个接口
IPerson

interface IPerson
{
    string FirstName { get; set; }
    string LastName { get; set; }
}

interface IStudent : IPerson
{
    int StudentNumber { get; set; }
}
我有一个类实现了
IStudent

class Student : IStudent
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int StudentNumber { get; set; }
}
现在我有一个抽象类
CommunityBase
,它有一个类型为
IPerson

abstract class CommunityBase
{
    public IPerson member;

    public CommunityBase(IPerson member)
    {
        this.member = member;
    }

    public void ShowName()
    {
        Console.WriteLine(this.member.FirstName + " " + this.member.LastName);
    }
}
我还有一个从
CommunityBase
派生的类,名为
University
。因为
University
是一个更具体的类,所以我想使用一个更具体的接口。因此,代码如下所示:

class University : CommunityBase
{
    public new IStudent member;

    public University(IStudent member)
        : base(member)
    {
        this.member = member;
    }

    public void ShowStudentNumber()
    {
        Console.WriteLine(this.member.StudentNumber);
    }
}
为了使所有这些都起作用,应该为
IStudent成员声明
new
关键字。我还需要在基类中分配一次
成员
字段,然后在派生类中分配一次

我想做的是在
社区库
构造函数中分配
成员
一次,但这样我就不能在
大学
类中使用
IStudent
中定义的属性或方法


上面所有的代码都按照预期编译和工作,但我想知道是否有一种更简单、更容易阅读的方法来实现这一点。从我所读到的内容来看,人们倾向于避免使用
new
关键字隐藏,如果我继续使用此代码,会不会有任何潜在问题?

将CommunityBase实现为泛型,将类型参数限制为IPerson

abstract class CommunityBase<T> where T : IPerson {
{
    public abstract T Member { get; }

    public void ShowName() {
        Console.WriteLine(this.Member.FirstName + " " + this.Member.LastName);
    }
}

class University : CommunityBase<IStudent>
{
    IStudent member;

    public University(IStudent member) {
        this.member = member;
    }

    public override IStudent Member { get { return member; } }

}
抽象类社区库,其中T:IPerson{
{
公共抽象T成员{get;}
public void ShowName(){
Console.WriteLine(this.Member.FirstName+“”+this.Member.LastName);
}
}
大学班级:社区基地
{
学生会员;
公立大学(学生会员){
this.member=成员;
}
公共重写IStudent成员{get{return Member;}}
}

使您的
社区基础
类成为通用类

abstract class CommunityBase<T> where T : IPerson
{
    protected T _member;
    public T Member { get return _member; }

    public CommunityBase(T member)
    {
        _member = member;
    }

    public virtual void ShowName()
    {
        Console.WriteLine(_member.FirstName + " " + _member.LastName);
    }
}

如果您自己的代码中有“new”,它本质上是说您不能同意自己的类型,这不会给您的代码带来很大的信心…对于“new”的问题-查看,特别是在帖子中链接到。否则需要考虑。但是如果
社区库
有一些类型为
IPerson
的字段,并且在
大学
中,他希望将它们更改为多个子类型,例如
IDean
IProfessor
,等等,那该怎么办呢?通过这种方法,他会这样做必须为每个字段指定一个泛型类型。这个答案完全解决了我的问题,但@Daniel提出了一个很好的观点。我想这个类看起来像CommunityBase,看起来不太好看。因为只有一个字段,所以只能有一个类型。但是如果您提到的类型都实现了
IPerson
,那么您可以创建一个例如,键入
TeachingStaff:CommunityBase
。但您只需在
CommunityBase
中列出
成员;
,就可以获得最大的灵活性,并在不同的人员类型中实现特定于人员类型的内容。例如,
ShowName
将是
IPerson
的成员,而不是
CommunityBas>的成员e
@OlivierJacot Descombes你能详细说明一下吗?我不明白使用类型
TechingStaff
如何解决你有三个不同字段的情况,每个字段都有一个不同的子类型
IPerson
。作为对你的编辑的回应:我仍然不相信你的解决方案适用于
社区
有许多不同的
IPerson
字段,在
University
中,您希望将每个字段更改为特定的
IPerson
:在这种情况下,使用
new
隐藏可能是最好的解决方案。当然,对于只有一个字段的特定情况,您的解决方案很好。@Daniel:参见我之前的评论。这个想法就是删除泛型内容,而是将特定于不同人员组的所有内容移动到
IPerson
。然后在
CommunityBase
中有一个
IPerson
列表,因为社区可能会有多个成员。但是由于OP只有一个
成员
字段,我没有在我的答案。虽然这个答案是正确的@Olivier Jacot Descombes的答案更完整一些。因为他从大学课堂上删除了成员字段。这是我的第一个问题。
class University : CommunityBase<IStudent>
{
    public University(IStudent member)
        : base(member)
    {
    }

    public override void ShowName()
    {
        Console.WriteLine(_member.FirstName + " " + _member.LastName +
             " Student-No. = " + _member.StudentNumber);
    }
}