Überlegungen insbesondere zu privaten Mitgliedern sind falsch
- Reflexionsbrüche Typ Sicherheit. Sie können versuchen, eine Methode aufzurufen, die (nicht mehr) existiert oder mit den falschen Parametern oder mit zu vielen Parametern oder nicht genug ... oder sogar in der falschen Reihenfolge (diese ist meine Lieblingsmethode :)). Übrigens könnte sich auch der Rückgabetyp ändern.
- Die Reflexion ist langsam.
Private Mitglieder Reflexion bricht Verkapselung Prinzip und damit Ihr Code wie folgt ausgesetzt wird :
- Erhöhen Sie die Komplexität Ihres Codes, da er das innere Verhalten der Klassen verarbeiten muss. Was verborgen ist, sollte verborgen bleiben.
- Erleichtert das Brechen Ihres Codes, da er kompiliert wird, aber nicht ausgeführt wird, wenn die Methode ihren Namen ändert.
- Erleichtert das Brechen des privaten Codes, da er, wenn er privat ist, nicht so aufgerufen werden soll. Vielleicht erwartet die private Methode einen inneren Zustand, bevor sie aufgerufen wird.
Was ist, wenn ich es trotzdem tun muss?
Es gibt Fälle, in denen Sie, wenn Sie von einem Dritten abhängig sind oder eine nicht exponierte API benötigen, einige Überlegungen anstellen müssen. Einige verwenden es auch, um einige Klassen zu testen, die sie besitzen, aber dass sie die Schnittstelle nicht ändern möchten, um den inneren Mitgliedern nur für Tests Zugriff zu gewähren.
Wenn Sie es tun, machen Sie es richtig
- Mildern Sie das leicht zu brechende:
Um das Problem der leicht zu brechenden Probleme zu verringern, ist es am besten, potenzielle Unterbrechungen durch Tests in Komponententests zu erkennen, die in einem kontinuierlichen Integrations-Build oder dergleichen ausgeführt werden. Dies bedeutet natürlich, dass Sie immer dieselbe Assembly verwenden (die die privaten Mitglieder enthält). Wenn Sie eine dynamische Last und Reflexion verwenden, spielen Sie gerne mit dem Feuer, aber Sie können immer die Ausnahme abfangen, die der Anruf möglicherweise erzeugt.
- Mildern Sie die Langsamkeit der Reflexion:
In den neuesten Versionen von .Net Framework hat CreateDelegate die von MethodInfo aufgerufenen Faktoren um den Faktor 50 übertroffen:
// The following should be done once since this does some reflection
var method = this.GetType().GetMethod("Draw_" + itemType,
BindingFlags.NonPublic | BindingFlags.Instance);
// Here we create a Func that targets the instance of type which has the
// Draw_ItemType method
var draw = (Func<TInput, Output[]>)_method.CreateDelegate(
typeof(Func<TInput, TOutput[]>), this);
draw
Anrufe sind etwa 50-mal schneller als die MethodInfo.Invoke
Verwendung draw
als Standard Func
:
var res = draw(methodParams);
Überprüfen Sie diesen Beitrag von mir , um Benchmark für verschiedene Methodenaufrufe zu sehen