Was ist das C # -Aquivalent von Freund?

Mögliche Duplikate:
Warum stellt C # das C ++ – Stil-Friend-Keyword nicht zur Verfügung?

Ich möchte, dass die privaten Membervariablen einer class für eine Testerklasse zugänglich sind, ohne sie anderen classn zu offenbaren.

In C ++ würde ich die Tester-class einfach als Freund deklarieren, wie mache ich das in C #? Kann mir jemand ein Beispiel geben?

Es gibt kein direktes Äquivalent von “Freund” – der nächste, der verfügbar ist (und es ist nicht sehr nah) ist InternalsVisibleTo . Ich habe dieses Attribut nur zum Testen verwendet – wo es sehr praktisch ist!

Beispiel: In AssemblyInfo.cs

 [assembly: InternalsVisibleTo("OtherAssembly")] 

Das Schrankäquivalent besteht darin, eine geschachtelte class zu erstellen, die auf die privaten Mitglieder der äußeren class zugreifen kann. Etwas wie das:

 class Outer { class Inner { // This class can access Outer's private members } } 

oder wenn Sie die Inner-class lieber in eine andere Datei einfügen möchten:

 Outer.cs partial class Outer { } Inner.cs partial class Outer { class Inner { // This class can access Outer's private members } } 

Nimm ein sehr häufiges Muster. Class Factory macht Widgets. Die Fabrikklasse muss sich mit den Interna herumschlagen, denn es ist die Fabrik. Beide sind in der gleichen Datei implementiert und sind, nach Design und Wunsch und Natur, eng gekoppelte classn – tatsächlich ist Widget tatsächlich nur ein Ausgabetyp von der Fabrik.

In C ++ machen Sie die Factory zu einem Freund der Widget-class.

In C #, was können wir tun? Die einzige vernünftige Lösung, die mir in den Sinn gekommen ist, ist die Erfindung einer Schnittstelle, IWidget, die nur die öffentlichen Methoden verfügbar macht und die IWidget-Schnittstellen von Factory zurückgibt.

Dies beinhaltet eine beträchtliche Menge an Langeweile – alle natürlich öffentlichen Eigenschaften wieder in der Schnittstelle auszusetzen.

In C # gibt es kein “Friend” -Schlüsselwort, aber eine Option zum Testen von privaten Methoden besteht darin, System.Reflection zu verwenden, um ein Handle für die Methode zu erhalten. Dadurch können Sie private Methoden aufrufen.

Eine class mit dieser Definition gegeben:

 public class Class1 { private int CallMe() { return 1; } } 

Sie können es mit diesem Code aufrufen:

 Class1 c = new Class1(); Type class1Type = c.GetType(); MethodInfo callMeMethod = class1Type.GetMethod("CallMe", BindingFlags.Instance | BindingFlags.NonPublic); int result = (int)callMeMethod.Invoke(c, null); Console.WriteLine(result); 

Wenn Sie Visual Studio Team System verwenden, können Sie VS veranlassen, automatisch eine Proxy-class mit privaten Zugriffsmethoden zu erstellen, indem Sie mit der rechten Maustaste auf die Methode klicken und “Unit-Tests erstellen …” auswählen.

Sie können einen Freundeszugriff simulieren, wenn die class, zu der Zugriffsberechtigungen erteilt wurden, sich in einem anderen Paket befindet und die Methoden, die Sie angeben, als intern oder intern geschützt gekennzeichnet sind. Sie müssen die Assembly, die Sie freigeben möchten, ändern und die folgenden Einstellungen zu AssemblyInfo.cs hinzufügen:

 // Expose the internal members to the types in the My.Tester assembly [assembly: InternalsVisibleTo("My.Tester, PublicKey=" + "012700000480000094000000060200000024000052534131000400000100010091ab9" + "ba23e07d4fb7404041ec4d81193cfa9d661e0e24bd2c03182e0e7fc75b265a092a3f8" + "52c672895e55b95611684ea090e787497b0d11b902b1eccd9bc9ea3c9a56740ecda8e" + "961c93c3960136eefcdf106955a4eb8fff2a97f66049cd0228854b24709c0c945b499" + "413d29a2801a39d4c4c30bab653ebc8bf604f5840c88")] 

Der öffentliche Schlüssel ist optional, abhängig von Ihren Anforderungen.