私はこのイベントクラスを持っています:
sealed class AnEvent : EventArgs
{
IEnumerable<ItemWrapper<AnAbstractClass>> Items { get; set; }
}
これは次のように使用されます:
class ItemsProcessor
{
delegate void OnItemsProcessedHandler(object sender, AnEvent e);
event OnItemsProcessedHandler OnItemsProcessed;
//...
}
私はこのラッパークラスを使用します:
sealed class ItemWrapper<T>
where T: AnAbstractClass
{
T Item { get; set; }
Metadata Metadata { get; set; }
ItemWrapper(T item, Metadata metadata)
{
Item = item;
Metadata = metadata;
}
}
ItemsProcessor
そして、私はクラスにこのメソッドを持っています:
internal void DoSomethingWithList<T>(IEnumerable<T> items)
where T: AnAbstractClass, new()
{
IEnumerable<ItemWrapper<T>> processedItems = WrapItems<T>(items);
OnItemsProcessed(this, new AnEvent() { Items = processedItems }); //error here
}
この問題は、このコード サンプルの最後の行にあります。localでのプロパティを設定しようとしたItems
とき。コンパイラは、 anを an に暗黙的にキャストできないと言って続行を拒否します。このメソッドに制約を追加したので大丈夫だと思いましたが、明示的にキャストした場合でも (括弧付きの古典的なキャストまたは を使用) 、.AnEvent
IEnumerable
IEnumerable<ItemWrapper<T>>
IEnumerable<ItemWrapper<AnAbstractClass>>
where T: AnAbstractClass, new()
Convert<>
InvalidCastException
メソッドの現在の回避策DoSomethingWithList
は次のとおりです。
var temp = processedItems.Select(x =>
{
return new ItemWrapper<AnAbstractClass>(x.Item, x.Metadata);
});
OnItemsProcessed(this, new AnEvent() { Items = temp });
今は問題なく動作してLINQ
いますが、リスト内のすべての項目を反復処理する必要があるこの変換を使用しないと、なぜ動作しないのでしょうか? 制約を追加したため、エラーなしでキャストできるはずであり、明示的なキャストを使用してコンパイラーにコードを受け入れさせても、例外が発生することは明らかです...誰でも何が問題なのかを指摘できますここ?
abstract class AnAbstractClass
{
}
class ItemClass : AnAbstractClass
{
}
試してみたい場合は、簡単にコピーして貼り付けるためのWrapItems
簡単な実装:
IEnumerable<ItemWrapper<T>> WrapItems<T>(IEnumerable<T> items)
where T : AnAbstractClass, new()
{
List<ItemWrapper<T>> ret = new List<ItemWrapper<T>>();
foreach (var item in items)
{
ret.Add(new ItemWrapper<T>(item, new Metadata()));
}
return ret;
}