私はこのようなことをしたい:
List<Child> childList = new List<Child>();
...
List<Parent> parentList = childList;
ただし、parentListは リスト 直接の祖先ではなく、子供の祖先の、私はこれを行うことができません。回避策はありますか(各要素を個別に追加する以外)?
タイプセーフにする方法がないため、直接キャストすることはできません。キリンのリストがあり、それを動物のリストにキャストした場合、キリンのリストにトラを入れることができます!もちろん、虎は動物のリストに入るかもしれないので、コンパイラはあなたを止めません。コンパイラがあなたを止めることができる唯一の場所は、安全でない変換です。
C#4では、SAFEインターフェイスと参照型でパラメーター化されたデリゲート型の共分散と反分散をサポートします。詳細はこちらをご覧ください:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
2009年に、エリックはC#4で状況が変わることを教えてくれました。
私の回答で使用したクラスは下部にあります。これを理解しやすくするために、「親」としてMammal
クラスを使用し、「子」としてCat
およびDog
クラスを使用します。猫と犬は両方とも哺乳類ですが、猫は犬ではなく、犬は猫ではありません。
これはまだ合法ではなく、次のことはできません。
_List<Cat> cats = new List<Cat>();
List<Mammal> mammals = cats;
_
何故なの?猫は哺乳類なので、猫のリストを_List<Mammal>
_に割り当てられないのはなぜですか?
なぜなら、_List<Cat>
_への参照を_List<Mammal>
_変数に格納できる場合、次のコードをコンパイルして、犬を猫のリストに追加できるからです。
_mammals.Add(new Dog());
_
それを許してはいけません! mammals
はcats
への単なる参照であることに注意してください。 Dog
はCat
から派生せず、Cat
オブジェクトのリストに含まれるビジネスはありません。
。NET Framework 4以降 、いくつかのジェネリックインターフェイスには、C#4で導入された out
Generic Modifierキーワードで宣言された共変型パラメーターがあります。 _IEnumerable<T>
_ これはもちろん_List<T>
_によって実装されます。
これは、canが_List<Cat>
_を_IEnumerable<Mammal>
_にキャストすることを意味します。
_IEnumerable<Mammal> mammalsEnumerable = cats;
_
_IEnumerable<out T>
_は「読み取り専用」インターフェースであるため、新しいDog
をmammalsEnumerable
に追加できません。つまり、Add()
メソッドはありませんが、 canは、_IEnumerable<Mammal>
_を消費できる場所であればどこでもcats
を使用します。たとえば、mammalsEnumerable
を_List<Dog>
_と連結して、新しいシーケンスを返すことができます。
_void Main()
{
List<Cat> cats = new List<Cat> { new Cat() };
IEnumerable<Mammal> mammalsEnumerable =
AddDogs(cats); // AddDogs() takes an IEnumerable<Mammal>
Console.WriteLine(mammalsEnumerable.Count()); // Output: 3. One cat, two dogs.
}
public IEnumerable<Mammal> AddDogs(IEnumerable<Mammal> parentSequence)
{
List<Dog> dogs = new List<Dog> { new Dog(), new Dog() };
return parentSequence.Concat(dogs);
}
_
クラス定義:
_public abstract class Mammal { }
public class Cat: Mammal { }
public class Dog : Mammal { }
_
はい、次のようにできます
var result = List.And(x => x.Parent.All(b => b.ParentId == value));