コレクション内のオブジェクトがすべて同じ基本クラスから派生しているが、一部は 1 つの派生型であり、一部は別の派生型である可能性がある異種コレクションを照会する簡単な方法はありますか?
たとえば、クラス階層は次のとおりです。
public class Ship
{
public string Name { get; set; }
public string Description { get; set; }
}
public class SailingVessel : Ship
{
public string Rig { get; set; }
public int NumberOfMasts { get; set; }
}
public class MotorVessel : Ship
{
public string Propulsion { get; set; }
public decimal TopSpeed { get; set; }
}
そして、これがクエリしたい XML ドキュメントです。
<?xml version="1.0" ?>
<ships xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ship xsi:type="sailingVessel">
<name>Cutty Sark</name>
<description>Tea clipper</description>
<rig>Ship</rig>
<numberOfMasts>3</numberOfMasts>
</ship>
<ship xsi:type="sailingVessel">
<name>Peking</name>
<description>Windjammer of the Flying P Line</description>
<rig>Barque</rig>
<numberOfMasts>4</numberOfMasts>
</ship>
<ship xsi:type="motorVessel">
<name>HMS Hood</name>
<description>Last British battlecruiser</description>
<propulsion>SteamTurbine</propulsion>
<topSpeed>28</topSpeed>
</ship>
<ship xsi:type="motorVessel">
<name>RMS Queen Mary 2</name>
<description>Last transatlantic passenger liner</description>
<propulsion>IntegratedElectricPropulsion</propulsion>
<topSpeed>30</topSpeed>
</ship>
<ship xsi:type="motorVessel">
<name>USS Enterprise</name>
<description>First nuclear-powered aircraft carrier</description>
<propulsion>Nuclear</propulsion>
<topSpeed>33.6</topSpeed>
</ship>
</ships>
XML ドキュメントをクエリして、その内容を Ship オブジェクトのリストに読み込むことができます。
XDocument xmlDocument = XDocument.Load("Ships.xml")
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
var records = (from record in xmlDocument.Descendants("ship")
let type = record.Attribute(xsi + "type").Value
select new Ship
{
Name = (string)record.Element("name"),
Description = (string)record.Element("description")
}).ToArray<Ship>();
これは以下を返します。
Ship[0] (type: Ship):
Name: Cutty Sark
Description: Tea clipper
Ship[1] (type: Ship):
Name: Peking
Description: Windjammer of the Flying P Line
Ship[2] (type: Ship):
Name: HMS Hood
Description: Last British battlecruiser
Ship[3] (type: Ship):
Name: RMS Queen Mary 2
Description: Last transatlantic passenger liner
Ship[4] (type: Ship):
Name: USS Enterprise
Description: First nuclear-powered aircraft carrier
しかし、私が本当に生産できるようにしたいのはこれです:
Ship[0] (type: SailingVessel):
Name: Cutty Sark
Description: Tea clipper
Rig: Ship
NumberOfMasts: 3
Ship[1] (type: SailingVessel):
Name: Peking
Description: Windjammer of the Flying P Line
Rig: Barque
NumberOfMasts: 4
Ship[2] (type: MotorVessel):
Name: HMS Hood
Description: Last British battlecruiser
Propulsion: SteamTurbine
TopSpeed: 28
Ship[3] (type: MotorVessel):
Name: RMS Queen Mary 2
Description: Last transatlantic passenger liner
Propulsion: IntegratedElectricPropulsion
TopSpeed: 30
Ship[4] (type: MotorVessel):
Name: USS Enterprise
Description: First nuclear-powered aircraft carrier
Propulsion: Nuclear
TopSpeed: 33.6
基本の Ship オブジェクトではなく、SailingVessel オブジェクトまたは MotorVessel オブジェクトを適切に初期化するように LINQ クエリを変更するにはどうすればよいですか?
2 つの選択を実行し、それぞれの基本クラス プロパティ (名前と説明) のオブジェクト初期化を複製する必要がありますか? 考えられるのはそれだけですが、関連するコードの重複は嫌いです。または、基本クラスのプロパティを初期化し、必要に応じて SailingVessel (Rig、NumberOfMasts) または MotorVessel (推進力、TopSpeed) の追加プロパティを初期化する方法はありますか?