0

次のシナリオに遭遇したとき、私は今日インターフェイスでいくつかの作業を行っていました。次の 2 つの単純なインターフェイスがあるとします。

public interface IItem { }
public interface IInventory
{
    ICollection<IItem> Items { get; }
}

を実装する単純なクラスを作成しましたがIInventory、この実装は次のように完全に問題ないことに気付きました。

public class BasicInventory1 : IInventory
{
    private Dictionary<int, IItem> items;
    public ICollection<IItem> Items
    {
        get { return items.Values; }
    }
}

ただし、この実装にはキャストが必要です。

public class BasicInventory2 : IInventory
{
    private Dictionary<int, IItem> items;
    public ICollection<IItem> Items
    {
        get { return (ICollection<IItem>)items; }
    }
}

1 つはキャストを必要とし、もう 1 つは必要としないのはなぜですか? どちらの場合でも返される両方のコレクションのオブジェクト型をチェックすると、両方が実際に を実装していることが確認されICollectionます。

ここでは魔法の種類の変換が内部で行われていると思われるため、共変/反変と関係があるようですが、正確に何が起こっているのかはよくわかりません。

4

5 に答える 5

3

Dictionary<int, IItem>実装しませんICollection<IItem>。そのような単純な。

キーを指定しないと辞書に追加できないため、そのインターフェイスを実装しても意味がありません。インターフェイスが意味不明。

これは実行時エラーです。これは、アイテムが Dictionary のサブクラスを参照してキャストが有効になる可能性があるためです。

于 2013-11-11T10:27:27.000 に答える
2

2番目の例に追加.Valuesする場合、キャストは必要ないと思います

public class BasicInventory2 : IInventory
{
    private Dictionary<int, IItem> items;
    public ICollection<IItem> Items
    {
       get { return items.Values; }
    }
}

これは、 items が Dictionary であり、 を実装しているためICollection<KeyValuePair<TKey, TValue>>です。

于 2013-11-11T10:26:34.330 に答える
0

あなたのBasicInventory1帰りにあなたの帰りだけ。 を返すので、キャストは必要ありません。items.ValuesBasicInventory2items.ValuesICollection

MSDN:

于 2013-11-11T10:26:49.827 に答える
0

このコードは無効であり、常にランタイム エラーが発生します。

    public class BasicInventory2 : IInventory
    {
        private Dictionary<int, IItem> items = new Dictionary<int, IItem>();

        public ICollection<IItem> Items
        {
            get
            {
                return (ICollection<IItem>) items;
            }
        }
    }

A Dictionary<int, IItem>は実装しませんがICollection<IItem>、 from から返される型は実装Dictionary<int, IItem>.Values ます。

したがって、答えは次のとおりです。

最初のケースはValues正しいタイプなので問題ありません。

2 番目のケースでは、コンパイラは間違った型を返そうとしていることを認識しているため、コンパイル エラーが発生します。

エラーをケースでオーバーライドすると、 runtime が得られますBadCastException

于 2013-11-11T10:32:23.357 に答える
-1

2 番目のコードでは辞書を戻り値として使用し、最初のコードでは値を使用します。Dictionary<int,IItems>譲り受けたものでICollection<KeyValuePair<int,IItems>>はございませんICollection<IItems>。したがって、キャストが必要です。

于 2013-11-11T10:27:44.363 に答える