0

私はこのイベントクラスを持っています:

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 に暗黙的にキャストできないと言って続行を拒否します。このメソッドに制約を追加したので大丈夫だと思いましたが、明示的にキャストした場合でも (括弧付きの古典的なキャストまたは を使用) 、.AnEventIEnumerableIEnumerable<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;
}
4

1 に答える 1

0

に変更ItemWrapperすると

sealed class ItemWrapper
{
    AnAbstractClass Item { get; set; }
    Metadata Metadata { get; set; }

    ItemWrapper(AnAbstractClass item, Metadata metadata) 
    {
        Item = item;
        Metadata = metadata;
    }
}

あなたは何を失いましたか?

于 2013-07-15T09:57:03.083 に答える