Nein, Sie können this
nicht in einem Konstruktorinitialisierer verwenden. Sie müssten anschließend den Aufruf Add(this)
hinzufügen - aber Sie können das im Base<TSelf>
-Konstruktor tun, solange Sie in TSelf
umwandeln. Sie müssen zuerst this
zu object
vor dem Gießen zu TSelf
aus ziemlich komplizierten Gründen um die Umwandlungen, die mit Typparametern erlaubt sind, leider werfen.
Sie können einen List<TSelf>
im Base
Konstruktor obwohl, ohne Problem erstellen. Hier ist Beispielcode beide von diesen zeigt:
abstract class Base<TSelf>
{
// Let's make it a property rather than a public field...
public ICollection<TSelf> List { get; }
public Base()
{
List = new List<TSelf>();
// This will obviously fail if you try to create a `Base<Foo>`
// from a class that isn't a Foo
TSelf selfThis = (TSelf) (object) this;
List.Add(selfThis);
}
}
class Implementation : Base<Implementation>
{
}
Sie eine Einschränkung zu TSelf
hinzufügen können, um das Gussversagen weniger wahrscheinlich versehentlich, aber nicht unmöglich:
abstract class Base<TSelf> where TSelf : Base<TSelf>
die Sie nicht stoppen Schreiben
class Implementation : Base<Implementation> {}
class Evil : Base<Implementation> {}
Dann, wenn Sie eine Instanz von Evil
konstruieren, sind Sie zu Anzeige versuchen d ein Evil
Verweis auf eine List<Implementation>
, die nicht funktionieren kann ... und die Besetzung kann Sie nicht davon abhalten, so weit zu kommen.
Casting 'this' zu' object' vor dem Casting zu 'TSelf' war die Lösung! –
In Bezug auf Ihren Kommentar _Dies wird offensichtlich scheitern_: kann dies nicht mit einem 'wo T: Base' erzwungen werden? –
@ManuelFaux: Yup, werde das erwähnen. –