web-dev-qa-db-ja.com

無効な分散:タイプパラメータ「T」は、「UserQuery.IItem <T> .ItemList」で逆分散的に有効である必要があります。 「T」は共変です

メソッドのコンパイル中にプロパティでエラーが発生するのはなぜですか?

public interface IFoo {}
public interface IBar<out T> where T : IFoo {}

public interface IItem<out T> where T: IFoo
{
    // IEnumerable<IBar<T>> GetList(); // works
    IEnumerable<IBar<T>> ItemList { get; set; } // Error!
}

エラー:

無効な分散:タイプパラメータ「T」は、「UserQuery.IItem <T> .ItemList」で逆分散的に有効である必要があります。 「T」は共変です。

27
ca9163d9

プロパティゲッター(get)とセッター(set)があるため、コンパイラエラーが発生します。プロパティゲッターの出力にはTが含まれているため、outは機能しますが、プロパティセッターの入力にはTが含まれるため、inが必要になります。修飾子。

outTがあるため、セッターを削除する必要があり、コンパイルされます。

public interface IItem<out T> where T : IFoo
{
    // IEnumerable<IBar<T>> GetList(); // works
    IEnumerable<IBar<T>> ItemList { get; } // also works
}

Tinジェネリック引数の場合、次のように機能します。

public interface IItem<in T> where T : IFoo
{
    IEnumerable<IBar<T>> ItemList { set; } 
}

ただし、両方を持つことはできません(out,in)同時に、ゲッターとセッターとの共変性/反変プロパティを持つことはできません。

36
nemesv

セッターは許可されていません。なぜなら、そうであれば、次のことができるからです。

public interface ISubFoo : IFoo { }

IItem<ISubFoo> item = //whatever
item.ItemList = new List<IBar<IFoo>>>();

これはタイプセーフではありません。

2
Lee