2010-06-15 7 views
13

Ich wollte im Grunde dies tun:Wie erben Sie von einem generischen Parameter?

class UILockable<T> : T 
    where T : UIWidget 
{ 
} 

Dies ist jedoch nicht funktioniert. Ich habe Leute gesehen empfehlen, dass Sie dies tun:

class UILockable<T> 
    where T : UIWidget 
{ 
    private T _base; 
} 

Das würde mich fordern, dass jede Funktion UILockable außer Kraft setzen würde es T. brauchen und uns darauf, dieses nicht möglich ist, da T von UIWidget ableiten können und haben einzigartige abstrakte/virtual eigene Methoden.

Gibt es keine Möglichkeit, einfach von T zu erben?

+0

Erwägen Sie, den generischen Typ zum Implementieren einer bestimmten Schnittstelle zu erzwingen. Sie können nicht wissen, welcher genaue Typ T ist, und wenn Sie nach bestimmten Methoden suchen, die ein T haben kann oder nicht, wird es nicht funktionieren. Machen Sie alle diese Objekte so, dass sie ILockable implementieren, was diese Methoden wie einen Vertrag erzwingt. – drharris

+1

Wenn Sie geschützte Methoden nicht außer Kraft setzen müssen, um Ihre Sperrlogik zu erreichen, können Sie dies mithilfe eines Sperrdienstobjekts neu gestalten, das UIWidget-Instanzen mit LockContext-Objekten verknüpft, die für Ihre Sperrlogik verwendet werden. Ich glaube nicht, dass die Vererbung eine gute konzeptionelle Lösung für das ist, was Sie versuchen zu tun, da Sie versuchen, die Funktionalität allgemein zu erweitern, nicht eine konkrete "ist-eine" -Beziehung auszudrücken. –

+0

möglich Duplikat von [Vererbung auf einem eingeschränkten generischen Typparameter] (http://stackoverflow.com/questions/1420581/inheritance-on-a-constrained-generic-type-parameter) – joce

Antwort

16

Sie können den generischen Typparameter nicht erben. C# -Generika unterscheiden sich stark von C++ - Vorlagen. Die Vererbung durch den type -Parameter erfordert, dass die Klasse eine vollständig andere Darstellung basierend auf dem type-Parameter aufweist, was bei .NET-Generics nicht der Fall ist. Sie sind auf der IL- und nativen Ebene identisch (für alle Argumente des Referenztyps).

3

Nein, gibt es nicht. Aber ich verstehe Ihre Argumentation nicht wirklich gegen mit UILockable<T> vererben UIWidget und leitet alle Anrufe auf Ihren T:

class UILockable<T> : UIWidget 
    where T : UIWidget 
{ 
    private readonly T t; 

    public void SomeMethod() 
    { 
     this.t.SomeMethod(); 
    } 
} 

Sie nicht über die Besonderheiten von T ‚s Umsetzung von UIWidget kümmern - nur, dass es ist eine Implementierung von UIWidget.

+3

Ich denke, was er sagt, ist, dass wenn Sie tun Sie es so, alle Methoden von 'T', die nicht von' UIWidget' spezifiziert sind, sind nicht zugänglich. –

+1

In diesem Fall müssten Sie weitere allgemeine Einschränkungen hinzufügen, so dass T UIWidget erweitert und auch einige Schnittstellen implementiert. –

3

Denk darüber auf diese Weise: Wenn Typ B erbt von Typ A, Sie erklärt, dass Bähnlich ist-A (wo Ähnlichkeit bedeutet, dass Sie B verwenden können überall, wo Sie erwarten, zu verwenden A). Nun, da eine solche Ähnlichkeit nicht symmetrisch ist Sie haben, dass B-A ähnlich ist, aber A ist nicht ähnlich wie B. Weiterhin kann B und C sowohl A ähnlich sein (das heißt sie beide stammen von A) ohne einander ähnlich zu sein.

Also, was Sie erklären wollen, ist, dass Freischaltbarer alles ähnlich ist, die UIWidget ähnlich ist, aber das ist unmöglich, weil Art Ähnlichkeit nicht transitiv ist (dh, wenn B-ähnlich ist A und C ähnlich ist zu A kann man nicht sagen B ist ähnlich zu C).

+0

@Robert Warum ist das nicht die Antwort? – AgentFire

+1

@AgentFire: Weil es den wesentlichen Punkt übersieht - 'Freischaltbare ' wäre ähnlich zu 'T', nicht andere Unterklassen von' UIWidget', und es wäre ähnlich aufgrund der erben das Verhalten von 'T'. –

0

Sie können nicht von einem generischen Typ-Argument erben. C# ist eine streng typisierte Sprache. Alle Typen und die Vererbungshierarchie müssen zum Zeitpunkt der Kompilierung bekannt sein. .Net-Generika unterscheiden sich erheblich von C++ - Vorlagen.

Und wenn Sie so sicher sind, dass das Typargument T vom Typ UIWidget sein wird, warum erben Sie nicht von UIWidget selbst. Sollte es jemals erlaubt sein [vorausgesetzt, ich nehme an, ich weiß, dass dies nie möglich sein wird], was würden Sie erreichen, indem Sie Ihre Klasse von T erben, die bereits vom Typ UIWidget ist? Zur Entwurfszeit werden Sie nur gegen UIWidget codieren, also warum nicht direkt von UIWidget erben.

+0

Warum nicht direkt von 'UIWidget' erben? * Mixins *. Nur weil das Mixin nur die essentielle Schnittstelle von 'UIWidget' nutzen kann, bedeutet das nicht, dass der Konsument nicht das Mixin-Verhalten und etwas spezialisierteres Widget-Verhalten * auf demselben Objekt * haben möchte. –

+0

Da diese Vererbung stark statisch typisiert und verboten ist, sind sie vollständig orthogonal. – Puppy

Verwandte Themen