Unsere Software verfügt über mehrere Klassen, die dynamisch über Reflexion gefunden werden sollten. Die Klassen haben alle einen Konstruktor mit einer bestimmten Signatur, über die der Reflektionscode Objekte instanziiert.
Wenn jedoch jemand prüft, ob auf die Methode verwiesen wird (z. B. über Visual Studio Code Lens), wird die Referenz über Reflection nicht gezählt. Menschen können ihre Referenzen verpassen und scheinbar nicht verwendete Methoden entfernen (oder ändern).
Wie sollen Methoden markiert / dokumentiert werden, die durch Reflexion aufgerufen werden sollen?
Idealerweise sollte die Methode so gekennzeichnet sein, dass sowohl Kollegen als auch Visual Studio / Roslyn und andere automatisierte Tools „sehen“, dass die Methode über Reflektion aufgerufen werden soll.
Ich kenne zwei Optionen, die wir verwenden können, aber beide sind nicht ganz zufriedenstellend. Da Visual Studio die Referenzen nicht finden kann:
- Verwenden Sie ein benutzerdefiniertes Attribut und markieren Sie den Konstruktor mit diesem Attribut.
- Ein Problem besteht darin, dass Attributeigenschaften keine Methodenreferenz sein können. Daher zeigt der Konstruktor weiterhin 0 Referenzen an.
- Kollegen, die mit dem benutzerdefinierten Attribut nicht vertraut sind, werden es wahrscheinlich ignorieren.
- Ein Vorteil meines aktuellen Ansatzes ist, dass der Reflexionsteil das Attribut verwenden kann, um den Konstruktor zu finden, den er aufrufen soll.
- Verwenden Sie Kommentare, um zu dokumentieren, dass eine Methode / ein Konstruktor über Reflektion aufgerufen werden soll.
- Automatisierte Tools ignorieren Kommentare (und Kollegen tun dies möglicherweise auch).
- XML-Dokumentationskommentare können verwendet werden, damit Visual Studio einen zusätzlichen Verweis auf die Methode / den Konstruktor zählt:
SeiMyPlugin
die Klasse, deren Konstruktor über Reflektion aufgerufen werden soll. Angenommen, der aufrufende Reflection-Code sucht nach Konstruktoren, die einenint
Parameter annehmen . In der folgenden Dokumentation wird gezeigt, dass das Codeobjektiv den Konstruktor mit 1 Referenz zeigt:
/// <see cref="MyPlugin.MyPlugin(int)"/> is invoked via reflection
Welche besseren Möglichkeiten gibt es?
Was ist die beste Vorgehensweise zum Markieren einer Methode / eines Konstruktors, die bzw. der über Reflexion aufgerufen werden soll?
quelle
Antworten:
Eine Kombination der vorgeschlagenen Lösungen:
Dies sollte den Kollegen (und meinem zukünftigen Selbst) die beabsichtigte Verwendung klarstellen.
<see>
-tag, um die Referenzanzahl für den Konstruktor / die Methode zu erhöhen.Dies zeigt, dass die Code-Linse und die Suchreferenzen zeigen, dass auf den Konstruktor / die Methode verwiesen wird.
UsedImplicitlyAttribute
[UsedImplicitly]
hat genau die beabsichtigte Semantik.PM> installieren
Install-Package JetBrains.Annotations
.SupressMessageAttribute
für die NachrichtCA1811: Avoid uncalled private code
.Zum Beispiel:
Die Lösung überträgt die beabsichtigte Verwendung des Konstruktors sowohl an menschliche Leser als auch an die drei statischen Code-Analysesysteme, die am häufigsten mit C # und Visual Studio verwendet werden.
Der Nachteil ist, dass sowohl ein Kommentar als auch ein oder zwei Anmerkungen etwas überflüssig erscheinen.
quelle
MeansImplicitUseAttribute
, dass Sie damit auch eigene Attribute erstellen können, die sichUsedImplicitly
auswirken. Dies kann in den richtigen Situationen viel Attributrauschen reduzieren.Ich hatte dieses Problem noch nie in einem .NET-Projekt, aber ich habe regelmäßig das gleiche Problem mit Java-Projekten. Mein üblicher Ansatz besteht darin, die
@SuppressWarnings("unused")
Anmerkung zu verwenden und einen Kommentar hinzuzufügen, der erklärt, warum (die Dokumentation des Grundes für das Deaktivieren von Warnungen ist Teil meines Standardcodestils - jedes Mal, wenn der Compiler etwas nicht herausfinden kann, gehe ich davon aus, dass es wahrscheinlich ist, dass ein Mensch Probleme hat zu). Dies hat den Vorteil, dass automatisch sichergestellt wird, dass statische Analysewerkzeuge wissen, dass der Code keine direkten Verweise enthalten soll, und dass für menschliche Leser ein detaillierter Grund angegeben wird.Das C # -Äquivalent von Java
@SuppressWarnings
istSuppressMessageAttribute
. Für private Methoden können Sie die Meldung CA1811 verwenden: Vermeiden Sie nicht aufgerufenen privaten Code . z.B:quelle
SuppressMessageAttribute
( msdn.microsoft.com/en-us/library/… ). Die Nachricht, die am nächsten kommt, lautetCA1811: Avoid uncalled private code
( msdn.microsoft.com/en-us/library/ms182264.aspx ); Ich habe noch keine Nachricht für den öffentlichen Code gefunden.Eine Alternative zur Dokumentation wäre, Unit-Tests durchzuführen, um sicherzustellen, dass die Reflection-Aufrufe erfolgreich ausgeführt werden.
Auf diese Weise sollte Ihr Build- / Testprozess Sie benachrichtigen, wenn jemand die Methoden ändert oder entfernt, dass Sie etwas kaputt gemacht haben.
quelle
Nun, ohne Ihren Code zu sehen, klingt es so, als wäre dies ein guter Ort, um eine Vererbung einzuführen. Vielleicht eine virtuelle oder abstrakte Methode, die der Konstruktor dieser Klassen aufrufen kann? Wenn Sie die Methode sind, die Sie markieren möchten, ist dies nur der Konstruktor, dann versuchen Sie wirklich, eine Klasse und keine Methode zu markieren, ja? In der Vergangenheit habe ich zum Markieren von Klassen eine leere Schnittstelle erstellt. Dann können Code-Inspektions-Tools und Refactoring nach Klassen suchen, die die Schnittstelle implementieren.
quelle