抽象クラスに基づくクラスの階層がありますDevice
。すべてのデバイスのリポジトリは次のようになります。
class Hardware
{
public readonly DeviceCollection<Switch> Switches = ...;
public readonly DeviceCollection<Light> Lights = ...;
}
where をDeviceCollection
実装しIEnumerable<T> where T : Device
ます。
すべてのデバイスで列挙する必要がありますが、現在のくだらないコードはこれを行います
protected override IEnumerator<Device> enumerate()
{
foreach (var light in Lights)
{
yield return light;
}
foreach (var @switch in Switches)
{
yield return @switch;
}
}
これは堅牢ではありません。新しいハードウェアDeviceCollection
を追加することがあり、上記の新しいイテレーションを追加するのを忘れがちです。だから私は少しの反省が助けになるだろうと考えました -DeviceCollection
フィールドのリストを怠惰に構築し、それを実行します。しかし、そのリストの宣言はどのように見えるでしょうか?
private List<DeviceCollection<T>> _collections;
コンパイルしません。どちらでもない
private List<DeviceCollection> _collections;
このリストを宣言するにはどうすればよいですか?
結果:IEnumerableが共変であるというTim Sの答えは、私の当面の問題を解決します。残りの小さな問題 (もっと簡単な解決策があるはずです!) は、反射を行う方法です。これが私の醜い醜いハックです:
_collections = new List<IEnumerable<Device>>();
var fields = GetType().GetFields( BindingFlags.Instance | BindingFlags.Public );
foreach (var field in fields)
{
if (field.FieldType.Name.Contains( "DeviceCollection" ))
{
_collections.Add( (IEnumerable<Device>)field.GetValue(this) );
}
}
これは、テスト
if (field.FieldType == typeof(DeviceCollection<>)
動作しません。