Lassen Sie uns sagen, dass ich eine generische Box
Klasse haben wollen, dass etwas im Inneren enthalten kann, so ist es ein Box<T>
. Box<T>
hat eine Transform
Methode, die eine Box<U>
zurückgibt: das hatMerkwürdiger wiederkehrend Schablonenmuster mit zusätzlichen generischen Typen
public Box<U> Transform<U>(Func<T, U> transform)
bisher ganz einfach. Allerdings benötige ich eigentlich eine Zusammenfassung Box
, da die Art, wie die Werte eingerahmt und transformiert werden, implementierungsspezifisch ist. (Ich kann keine Schnittstelle haben, da es andere Methoden gibt, die durch die Komposition von abstrakten Methoden implementiert werden, aber das ändert sowieso nichts).
Natürlich möchte ich meine überschriebene Transform
Methoden, um eine entsprechende Unterklasse von Box
, nicht Box
selbst zurückgeben. Da Rückgabetypen von überragender Methoden in # C invariant sind, wende ich mich an die curiously recurring template pattern (siehe IComparable<T>
):
public abstract class Box<B, T> where B : Box<B, T>
Nun sollte sich jede Klasse I von Box<B, T>
erben beziehen oder bricht die Hölle los:
public class FooBox<T> : Box<FooBox, T>
jedoch zerstört diese vollständig die Transform
Methode:
public abstract Box<B, U> Transform<U>(Func<T, U> transform);
schlägt mit 0 kompilieren. Das ist sinnvoll, da der Rückgabetyp jetzt Box<B, U>
ist und B Box<B, T>
ist, was nicht Box<B, U>
ist.
Die einfache fix wird nicht funktionieren:
public abstract Box<B, U> Transform<U>(Func<T, U> transform) where B : Box<B, U>;
nicht mit 'Test.Box<B,T>.Transform<U>()' does not define type parameter 'B' (CS0699)
kompilieren.
Gibt es eine Möglichkeit, dies zu lösen, oder habe ich mich wirklich in eine Ecke gemalt?
Können Sie machen es nur eine 'Box ' und Implementierung spezifischer Informationen in über Factory-Methoden übergeben? –
@MillieSmith entfernen CRTP würde natürlich funktionieren, aber das würde dazu führen, dass nicht in der Lage sein, diese Methoden wie 'Box Merge (Box andere, Func Merge)' tatsächlich kompatible akzeptieren 'Box's. –
Alexey