سؤال

I try to give an example as simple as possible but the very essence of the question is quite confusing at least to me.

In order to reuse code and not repeat my self I have an interface IStudent that implements another interface IPerson.

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

interface IStudent : IPerson
{
    int StudentNumber { get; set; }
}

I have a class implementing IStudent

class Student : IStudent
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int StudentNumber { get; set; }
}

Now I have an abstract class CommunityBase that has a field of type 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);
    }
}

I also have a class derived from CommunityBase called University. Because University is a more concrete class I want to use a more concrete interface. So the code is the following:

class University : CommunityBase
{
    public new IStudent member;

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

    public void ShowStudentNumber()
    {
        Console.WriteLine(this.member.StudentNumber);
    }
}

In order for all this to work the new keyword should be declared for the IStudent member. Also I would need to assign the member field once in the base class and again in the derived class.

What I want to do is assign member once in the CommunityBase constructor but this way I cannot use the properties or methods defined in IStudent in the University class.

All of the above code compiles and works as expected but I was wondering if there is an easier and more simple/easy to read way to do this. From what I read people tend to avoid using the new keyword for hiding if I continue using this code would there be any potential issues?

هل كانت مفيدة؟

المحلول

Make your CommunityBase class generic

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);
    }
}

Also make ShowName virtual, this enables more concrete classes to override it.

class University : CommunityBase<IStudent>
{
    public University(IStudent member)
        : base(member)
    {
    }

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

نصائح أخرى

Implement CommunityBase as a generic, constraining the type argument to 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; } }

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top