C#
定石5:共変・反変の罠— IEnumerable<T>は共変・IList<T>は不変
出典: C# のコレクション選び — 配列 / List / IEnumerable / IList の使い分け完全ガイド — 定石5:共変・反変の罠— IEnumerable<T>は共変・IList<T>は不変
// ✅定石5:共変(covariance)の例
class Animal { }
class Dog : Animal { }
// ✅ IEnumerable<Dog>はIEnumerable<Animal>に代入可能(共変・out T)
IEnumerable<Dog> dogs = new List<Dog> { new Dog(), new Dog()};
IEnumerable<Animal> animals = dogs; // OK
//「Dogの列挙はAnimalの列挙としても扱える」
// ❌ List<Dog>はList<Animal>に代入できない(不変)
List<Dog> dogList = new List<Dog>();
// List<Animal> animalList = dogList; //コンパイルエラー
//「List<Animal>にCatをAddされる可能性があるので不可」
// ❌ IList<Dog>もIList<Animal>に代入できない(不変)
IList<Dog> dogIList = new List<Dog>();
// IList<Animal> animalIList = dogIList; //コンパイルエラー
//「IList<Animal>.Add(new Cat())ができてしまうので不可」
▸ この snippet は実行結果未収録
▸ 実行結果は未収録です
Source収録記事
この snippet は記事の「定石5:共変・反変の罠— IEnumerable<T>は共変・IList<T>は不変」セクションに登場する。コードの前後の文脈・ハマりどころの解説は記事本文で。
同じ記事から
4 件// ✅定石1:配列T[] の基本 int[] daysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; string[] weekDays = new string[7] { "月", "火", "水", "木", "金", "土", "日" };未収録
定石1:配列T[] —固定長・最速だがAPIでは出番が絞られる
#30be80acb5d1
// ✅定石2: List<T>の基本 var customers = new List<CustomerVm>(); //追加未収録
定石2: List<T> —可変長・最も多用される実装型
#a559247150e8
// ✅定石3: IEnumerable<T>と遅延評価 public IEnumerable<CustomerVm> GetActiveCustomers() { return _db.Customers
▶ 実行可
定石3: IEnumerable<T> —遅延評価・LINQの基本型
#492870f19ead
// ✅定石4: IList<T>をメソッド引数で受ける public void ProcessCustomers(IList<CustomerVm> customers) { //インデックスアクセス未収録
定石4: IList<T> —メソッド引数の汎用型
#3ab6caaff422
