Dies führt zu einer Ausnahme bei der Kompilierung:
public sealed class ValidatesAttribute<T> : Attribute
{
}
[Validates<string>]
public static class StringValidation
{
}
Mir ist klar, dass C # keine generischen Attribute unterstützt. Nach langem Googeln kann ich den Grund jedoch nicht finden.
Weiß jemand, warum generische Typen nicht abgeleitet werden können? Attribute
? Irgendwelche Theorien?
c#
generics
.net-attributes
Bryan Watts
quelle
quelle
abstract class Base<T>: Attribute {}
könnte verwendet werden, um Nicht- Attribute zu erstellen. generische abgeleitete Klassen wie diese:class Concrete: Base<MyType> {}
[DependsOnProperty<Foo>(f => f.Bar)]
oder[ForeignKey<Foo>(f => f.IdBar)]
...Antworten:
Nun, ich kann nicht antworten, warum es nicht verfügbar ist, aber ich kann bestätigen, dass es sich nicht um ein CLI-Problem handelt. Die CLI-Spezifikation erwähnt es nicht (soweit ich sehen kann) und wenn Sie IL direkt verwenden, können Sie ein generisches Attribut erstellen. Der Teil der C # 3-Spezifikation, der dies verbietet - Abschnitt 10.1.4 "Klassenbasisspezifikation" gibt keine Rechtfertigung.
Die mit Anmerkungen versehene ECMA C # 2-Spezifikation enthält ebenfalls keine hilfreichen Informationen, obwohl sie ein Beispiel dafür enthält, was nicht zulässig ist.
Meine Kopie der kommentierten C # 3-Spezifikation sollte morgen eintreffen ... Ich werde sehen, ob das weitere Informationen liefert. Auf jeden Fall ist es definitiv eher eine Sprachentscheidung als eine Laufzeitentscheidung.
EDIT: Antwort von Eric Lippert (umschrieben): Kein besonderer Grund, außer um Komplexität sowohl in der Sprache als auch im Compiler für einen Anwendungsfall zu vermeiden, der nicht viel Wert hinzufügt.
quelle
Ein Attribut schmückt eine Klasse zur Kompilierungszeit, aber eine generische Klasse erhält ihre endgültigen Typinformationen erst zur Laufzeit. Da das Attribut die Kompilierung beeinflussen kann, muss es zur Kompilierungszeit "vollständig" sein.
Weitere Informationen finden Sie in diesem MSDN-Artikel .
quelle
Ich weiß nicht, warum es nicht erlaubt ist, aber dies ist eine mögliche Problemumgehung
quelle
Dies ist nicht wirklich generisch und Sie müssen immer noch eine bestimmte Attributklasse pro Typ schreiben, aber Sie können möglicherweise eine generische Basisschnittstelle verwenden, um ein wenig defensiv zu codieren, weniger Code als sonst erforderlich zu schreiben, Vorteile des Polymorphismus zu erzielen usw.
quelle
Das ist eine sehr gute Frage. Nach meiner Erfahrung mit Attributen, ich denke , die Einschränkung vorhanden ist , weil , wenn auf einem Attribut reflektieren würde es einen Zustand schaffen , in dem Sie für alle mögliche Typen Permutationen müßten überprüfen:
typeof(Validates<string>)
,typeof(Validates<SomeCustomType>)
usw ...Wenn meiner Meinung nach je nach Typ eine benutzerdefinierte Validierung erforderlich ist, ist ein Attribut möglicherweise nicht der beste Ansatz.
Vielleicht wäre eine Validierungsklasse, die einen
SomeCustomValidationDelegate
oder einenISomeCustomValidator
als Parameter verwendet, ein besserer Ansatz.quelle
Dies ist derzeit keine C # -Sprachenfunktion, es gibt jedoch viele Diskussionen über das offizielle C # -Sprach-Repo .
Aus einigen Besprechungsnotizen :
quelle
Meine Problemumgehung ist ungefähr so:
quelle