继承,还是我应该使用组合?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了继承,还是我应该使用组合?相关的知识,希望对你有一定的参考价值。
让我们说我有一堂课
public class Transfer
{
prop1
prop2
....
public List<SubTransfer> SubTransfers { get; set; }
}
我从连接数据库的函数得到的
现在我希望有一个类,它可以为Transfer和每个SubTransfer添加一个状态。
一个问题是我应该在这里使用继承吗?还是作文?
我认为继承,所以我试图做这样的事情:
public ExtendedSubTransfer : SubTransfer
{
public StatusEnum Status { get; set; }
}
public ExtendedTransfer : Transfer
{
public StatusEnum Status { get; set;}
}
我的问题是我不知道如何做到这一点,我将获得使用扩展传输时的扩展SubTransfer列表。
我知道我可以使用关键字new覆盖SubTransfers,如下所示:
public new List<ExtendedSubTransfers> SubTransfers {get; set;}
它是“合法的”吗?或者你有其他建议吗?
谢谢您的帮助!
它会编译,但它可能不会做你想要的。请记住,List<ExtendedSubTransfer>
不会扩展List<SubTransfer>
。例如,如果您有任何使用基类的操作,您将无法获得所需的操作。为了演示,让我们假装基类具有ID并且您想要打印ID。
public void PrintIds()
{
ExtendedTransfer extendedTransfer = _database.GetExtendedTransfer(...);
PrintSubTransferIds(extendedTransfer);
}
private PrintSubTransferIds(Transfer transfer)
{
foreach(var subTransfer in transfer.SubTransfers)
{
Console.WriteLine(subTransfer.Id);
}
}
除非您在从数据库加载项目时执行一些非常奇怪的操作,否则上述方法将无效。例如,如果您的加载代码看起来像......
public GetExtendedTransfer(...)
{
ExtendedTransfer result = new ExtendedTransfer();
List<ExtendedSubTransfer> subTransfers = _connection.QueryForSubTransfers(...);
result.SubTransfers = subTransfers;
return result;
}
然后它将无法正常工作。它不会打印任何子转移ID,因为transfer.SubTransfers
将是一个空列表。相反,当你从数据库加载时,你必须做一些奇怪的事情......
public GetExtendedTransfer(...)
{
ExtendedTransfer result = new ExtendedTransfer();
List<ExtendedSubTransfer> subTransfers = _connection.QueryForSubTransfers(...);
result.SubTransfers = subTransfers;
Transfer subtypedResult = result;
subtypedResult.SubTransfers = subTransfers.Cast<SubTransfer>();
return result;
}
此外,以下情况将是编译时错误:
public void PrintIds()
{
ExtendedTransfer extendedTransfer = _database.GetExtendedTransfer(...);
PrintSubTransferIds(extendedTransfer.SubTransfers);
}
private PrintSubTransferIds(List<SubTransfer> subTransfers)
{
foreach(var subTransfer in subTransfers)
{
Console.WriteLine(subTransfer.Id);
}
}
这将无法编译,因为extendedTransfer.SubTransfers
的类型为List<ExtendedSubTransfer>
,无法分配给List<SubTransfer>
。
更新:那你该怎么办?
C#(4.X及以上)允许在covariance上使用certain interfaces,例如IReadOnlyList
(C#4.5及以上)。这样你就可以......
public class Transfer
{
public virtual IReadOnlyList<SubTransfer> SubTransfers { get; private set; }
public void SetSubTransfers(List<SubTransfer> subTransfers)
{
SubTransfers = subTransfers;
}
}
public class ExtendedTransfer
{
private List<ExtendedSubTransfer> _subTransfers;
public override IReadOnlyList<SubTransfer> SubTransfers
{
get { return _subTransfers; }
}
public void SetSubTransfers(List<ExtendedSubTransfer> subTransfers)
{
_subTransfers = subTransfers;
}
}
这将是我解决问题的最佳尝试。但是,您没有提到如何从数据库中获取实体。我不认为EntityFramework
默认会对这种场地安排感到非常满意。
以上是关于继承,还是我应该使用组合?的主要内容,如果未能解决你的问题,请参考以下文章