我尽量给出一个尽可能简单的例子,但问题的本质至少让我感到困惑。
为了重用代码而不重复我自己,我有一个实现另一个接口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);
}
}
为了使所有这些工作正常,应为new
声明IStudent member
关键字。另外,我需要在基类中分配member
字段一次,然后再在派生类中分配。
我想要做的是在member
构造函数中分配CommunityBase
一次,但这样我就无法使用IStudent
类中University
中定义的属性或方法。
以上所有代码都按预期编译和工作,但我想知道是否有更简单,更简单/易读的方法来执行此操作。根据我的阅读,如果我继续使用此代码,那么人们往往会避免使用new
关键字进行隐藏吗?
答案 0 :(得分:2)
将CommunityBase
类设为通用
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);
}
}
同样使ShowName
为虚拟,这使得更具体的类可以覆盖它。
class University : CommunityBase<IStudent>
{
public University(IStudent member)
: base(member)
{
}
public override void ShowName()
{
Console.WriteLine(_member.FirstName + " " + _member.LastName +
" Student-No. = " + _member.StudentNumber);
}
}
答案 1 :(得分:1)
将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; } }
}