web-dev-qa-db-de.com

Von einer generischen Basisklasse übernehmen, eine Einschränkung anwenden und eine Schnittstelle in C # implementieren

Dies ist eine Syntaxfrage. Ich habe eine generische Klasse, die von einer generischen Basisklasse erbt und eine Einschränkung auf einen der Typparameter anwendet. Ich möchte auch, dass die abgeleitete Klasse eine Schnittstelle implementiert. Für mein Leben kann ich nicht die richtige Syntax herausfinden.

Das ist was ich habe:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar { ... }

Das erste, was mir in den Sinn kam, war folgendes:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar, IFoo { ... }

Dies ist jedoch falsch, da T2 dazu erforderlich ist, IBar und IFoo zu implementieren, nicht DerivedFoo, um IFoo zu implementieren.

Ich habe ein bisschen Googling ausprobiert, habe Doppelpunkte, Semikolons usw. verwendet, aber ich bin kurz aufgetaucht. Ich bin mir sicher, dass die Antwort einfach klatschend ist.

83
Dan Rigby

Sie schließen die gesamte Signatur Ihrer Klasse ein, bevor Sie generische Einschränkungen definieren.

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}
129
Adam Robinson

Meine Empfehlung: Wenn Sie eine Frage zur Syntax der C # -Sprache haben, lesen Sie die Spezifikation. Deshalb veröffentlichen wir es. Sie möchten Abschnitt 10.1 lesen.

Um Ihre spezifische Frage zu beantworten, lautet die Reihenfolge der Dinge in einer Klassendeklaration:

  • attribute in eckigen Klammern
  • modifikatoren ("public", "static" usw.)
  • "teilweise"
  • "Klasse"
  • der Klassenname
  • eine durch Kommas getrennte Liste von Typparameterdeklarationen in spitzen Klammern
  • ein Doppelpunkt folgte einer durch Kommas getrennten Liste von Basistypen (Basisklasse und implementierte Schnittstellen, Basisklasse muss zuerst gehen, wenn es einen gibt)
  • typparameter-Einschränkungen
  • der Körper der Klasse, umgeben von geschweiften Klammern
  • ein Semikolon

Alles in dieser Liste ist optional, mit Ausnahme von "Klasse", dem Namen und dem Hauptteil, aber alles muss in dieser Reihenfolge erscheinen, wenn es angezeigt wird.

15
Eric Lippert
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }
6
Stan R.
public class KeyAndValue<T>
{
    public string Key { get; set; }
    public virtual T Value { get; set; }
}

public class KeyAndValue : KeyAndValue<string>
{
    public override string Value { get; set; }
}

Dies ist eine Erweiterung der vorhandenen Antworten. Der Standardwert ist string, wenn Sie keinen Typ angeben. Ich habe keine Schnittstelle implementiert, aber das sollte nichts anderes als üblich erfordern.

0
user875234