誰かが out T 部分の使用法を例で説明できますか?
もちろん。IEnumerable<T>
は共変です。つまり、次のことができます。
static void FeedAll(IEnumerable<Animal> animals)
{
foreach(Animal animal in animals) animal.Feed();
}
...
IEnumerable<Giraffe> giraffes = GetABunchOfGiraffes();
FeedAll(giraffes);
「共変」とは、型引数の代入互換関係がジェネリック型で保持されることを意味します。Giraffe
は と代入互換性があるAnimal
ため、その関係は構築された型で保持されます:IEnumerable<Giraffe>
は と代入互換性がありIEnumerable<Animal>
ます。
インターフェイスとデリゲートにのみ適用され、クラスには適用されないのはなぜですか?
クラスの問題は、クラスが可変フィールドを持つ傾向があることです。例を見てみましょう。これを許可したとします。
class C<out T>
{
private T t;
では、先に進む前に、この質問をよく考えてください。フィールドをデフォルト以外に設定するメソッドをコンストラクターの外に置くことはできますか?C<T>
t
タイプセーフである必要がC<T>
あるため、T を引数として取るメソッドを使用できなくなりました。T のみを返すことができます。では、誰が t を設定し、設定した値をどこから取得するのでしょうか?
共変クラス型は、クラスがimmutableである場合にのみ機能します。そして、C# で不変クラスを作成する良い方法がありません。
できればよかったのですが、与えられた CLR 型システムと一緒に暮らす必要があります。将来的には、不変クラスと共変クラスの両方をより適切にサポートできるようになることを願っています。
この機能に興味がある場合は、この機能をどのように設計および実装したかについての私の長いシリーズを読むことを検討してください。下から始めます。
https://blogs.msdn.microsoft.com/ericlippert/tag/covariance-and-contravariance/