背景
若干ハマったけど解決できたのでメモがてら共有させていただきます。
環境
OS: Windows 10 Pro
IDE: Visual Studio 2017 Enterprise Version 15.9.40
Target Framework: .NET Framework 4.7
概要
親クラス(Parent)を継承した複数の子クラス(Child1~3)のListをポリモーフィズム的に処理したく、
保持用クラス(Hoji)のobject型変数(obj)に突っ込んで、Listとして保持しておいた。
その後、Listをforeachで反復処理しようとした際に、objからforeachで列挙可能な形に変換するのにちょっと躓いた話。
コード
定義
// 親クラス
class Parent
{
public string Name { get; set; }
}
// 子クラス(1~3)
class Child1 : Parent { }
class Child2 : Parent { }
class Child3 : Parent { }
// 保持クラス
class Hoji
{
public object obj { get; set; }
}
準備
// 各子クラスに要素を持たせる。
List<Child1> childList1 = new List<Child1>
{
new Child1 { Name = "aaa" },
new Child1 { Name = "bbb" },
new Child1 { Name = "ccc" }
};
List<Child2> childList2 = new List<Child2>
{
new Child2 { Name = "あああ" },
new Child2 { Name = "いいい" },
new Child2 { Name = "ううう" }
};
List<Child3> childList3 = new List<Child3>
{
new Child3 { Name = "111" },
new Child3 { Name = "222" },
new Child3 { Name = "333" }
};
// 保持用リストに格納
List<Hoji> hojiList = new List<Hoji>
{
new Hoji { obj = childList1 },
new Hoji { obj = childList2 },
new Hoji { obj = childList3 },
};
処理
// こうしようとした
foreach (var hoji in hojiList)
{
foreach (var child in hoji.obj as List<Parent>)
{
Console.WriteLine(child.Name);
// ⇒ System.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません。
}
}
// こうすればできた
foreach (var hoji in hojiList)
{
foreach (var child in hoji.obj as IEnumerable<Parent>)
{
Console.WriteLine(child.Name);
// ⇒ "aaa"
// "bbb"
// "ccc"
// "あああ"
// "いいい"
// "ううう"
// "111"
// "222"
// "333"
}
}
感想
正直、なんでできるのかまで調べる余裕がなくてわかってません。
いろいろ試した結果、IEnumerableでできたってことは遅延評価が関わってるのかなーってとこで止まってます。
気が向いた方は教えていただけると幸いです。