2017-08-27 2 views
1

Gibt es eine Möglichkeit, "das" an den Basiskonstruktor zu übergeben?Übergabe von "this" an Basiskonstruktor

abstract class Base<TSelf> 
{ 
    public ICollection<TSelf> List; 

    public Base(ICollection<TSelf> list, TSelf self) 
    { 
     List = list; 
     List.Add(self); 
    } 
} 

class Implementation : Base<Implementation> 
{ 
    public Implementation() : base(new List<Implementation>(), this) 
    { 
    } 
} 

Offensichtlich gibt es einen Übersetzungsfehler im Konstruktor von Implementation wo this zu base geben wird.

Ich sehe auch keine Möglichkeit, list bei Base Ebene instanziieren.

Antwort

6

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.

+0

Casting 'this' zu' object' vor dem Casting zu 'TSelf' war die Lösung! –

+0

In Bezug auf Ihren Kommentar _Dies wird offensichtlich scheitern_: kann dies nicht mit einem 'wo T: Base' erzwungen werden? –

+0

@ManuelFaux: Yup, werde das erwähnen. –

Verwandte Themen