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