【发布时间】:2022-10-14 23:28:42
【问题描述】:
为简洁起见,我简化了代码。
有两个基类Document 和Line 以及从它们派生的两个类DocumentPlus 和LinePlus。
Document 和 DocumentPlus 分别包含 List<Line> 和 List<LinePlus>。
public class Test
{
public class Document
{
public List<Line> Lines = new List<Line>();
}
public class Line
{
public string? A;
}
public class DocumentPlus : Document
{
public new List<LinePlus> Lines = new List<LinePlus>();
}
public class LinePlus : Line
{
public string? B;
}
public Test()
{
var x = new DocumentPlus();
x.Lines = new List<LinePlus>()
{
new LinePlus() { A = "123", B = "456" },
new LinePlus() { A = "789", B = "101" },
new LinePlus() { A = "112", B = "131" }
};
var y = (Document)x;
var z = y.Lines;
// Z should be the Lines entered above but as their base type
// Just not sure how to do it!
}
}
将DocumentPlus 实例转换为Document 时,有什么方法可以将List<LinePlus> 转换为List<Line>?
谢谢!
【问题讨论】:
-
理想情况下,我不想更改类结构(因为这反映了在整个程序中大量使用的类),但这种工作更重要。
-
在
Document基类中使用(只读)IEnumerable而不是 List 可以吗? IEnumerable 是协变的,这意味着List<LinePlus>既是IEnumerable<LinePlus>也是IEnumerable<Line>。 -
您原来的计划没有奏效,因为它违反了LSP。考虑以下示例代码:
DocumentPlus dp = ...; Document d = dp; d.Lines.Add(new SomeOtherSubtypeOfLine());。这通常通过在基类中将 Lines 设为只读来“修复”,从而启用协变。 -
@Heinzi 使用
private IEnumerable<Line> _Lines { get; set; } = new List<Line>();,然后分别在Document和DocumentPlus中实现两个公共List<Line>和new List<LinePlus>,完全按照我想要的方式工作。感谢您的回答! -
@Heinzi 如果您将其发布为答案,我将接受作为解决方案!
标签: c# inheritance casting