Während ein Design mit verschachtelten generischen Sammlungen Implementierung stolperte ich über diese Beschränkungen offenbar von C# 's invariant Generics verursacht:Verschachtelte generische Sammlungen: Wie implementiert man die Referenz von einem Artikel zu einem Container?
Cannot convert from 'Collection<subtype of T> to 'Collection<T>'
Das heißt, wird Folgendes nicht, offenbar wegen der Invarianz von Generics arbeiten:
class Outer<TInner, TInnerItem> where TInner : Inner<TInnerItem>
{
public void Add(TInner item)
{
item.Outer = this; // ERROR:
// Cannot implicitly convert from Outer<TInner, TInnerItem>
// to Outer<Inner<TInnerItem>, TInnerItem>
}
}
class Inner<TInnerItem> : ICollection<TInnerItem>
{
Outer<Inner<TInnerItem>, TInnerItem> _outer;
public Outer<Inner<TInnerItem>, TInnerItem> Outer
{
set { _outer = value; }
}
}
(im eigentlichen Code, sowohl Inner<>
und Outer<>
ICollection<>
implementieren.)
muss ich die Inner<>
Objekte, die auf ihre Containersammlung verweisen sollen, um auf einige ihrer Daten zuzugreifen.
Wie würden Sie diese verschachtelten Sammlungen implementieren, vorzugsweise mit einem generischen Ansatz wie oben beschrieben? Wie würden Sie den Verweis auf die Containersammlung in der Klasse Inner<>
festlegen?
Prost!
abstract class OuterBase<TInnerItem>
{
}
class Outer<TInner, TInnerItem> : OuterBase<TInnerItem> where TInner : Inner<TInnerItem>
{
public void Add(TInner item)
{
item.Outer = this; // Compiles
}
}
class Inner<TInnerItem> : ICollection<TInnerItem>
{
OuterBase<TInnerItem> _outer;
public OuterBase<TInnerItem> Outer
{
set { _outer = value; }
}
}
Oder für C# 4.0 warten, die co/kontravarianten generische Schnittstellen führt:
Ich kann meinen Kopf nicht um Ihre Klassen wickeln. Wenn Sie ihnen deutlichere Namen geben, kann ich vielleicht versuchen zu verstehen, was Sie zu tun versuchen. – DonkeyMaster