it-swarm.com.de

Was ist das C # -Äquivalent von friend?

Mögliches Duplikat:
Warum stellt C # das C++ - Schlüsselwort "friend" nicht zur Verfügung?

Ich möchte, dass auf die privaten Member-Variablen einer Klasse eine Testerklasse zugreifen kann, ohne sie anderen Klassen auszusetzen.

In C++ würde ich die Testerklasse einfach als Freund deklarieren. Wie mache ich das in C #? Kann mir jemand ein Beispiel geben?

174
Ben L

Es gibt kein direktes Äquivalent zu "Freund" - der nächste verfügbare (und nicht sehr nahe stehende) ist InternalsVisibleTo . Ich habe dieses Attribut bisher nur zum Testen verwendet - wo es sehr praktisch ist!

Beispiel: Platzierung in AssemblyInfo.cs

[Assembly: InternalsVisibleTo("OtherAssembly")]
247
Jon Skeet

Das Closet-Äquivalent besteht darin, eine verschachtelte Klasse zu erstellen, die auf die privaten Mitglieder der äußeren Klasse zugreifen kann. Etwas wie das:

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

oder wenn Sie die innere Klasse 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
    }
}
73
sjp

Nehmen Sie ein sehr verbreitetes Muster. Class Factory macht Widgets. Die Factory-Klasse muss sich über die Interna lustig machen, denn es ist die Factory. Beide werden in derselben Datei implementiert und sind von Design und Wunsch sowie von Natur aus eng miteinander verknüpfte Klassen - Widget ist in der Tat nur ein Ausgabetyp aus der Fabrik.

Machen Sie in C++ die Factory zu einem Freund der Widget-Klasse.

Was können wir in C # tun? Die einzige vernünftige Lösung, die mir in den Sinn gekommen ist, besteht darin, eine Schnittstelle, IWidget, zu erfinden, die nur die öffentlichen Methoden verfügbar macht und die Factory IWidget-Schnittstellen zurückgeben lässt.

Dies erfordert einiges an Mühe - alle natürlich öffentlichen Objekte werden in der Schnittstelle wieder freigelegt.

42
Freddy mac

In C # gibt es kein 'friend'-Schlüsselwort, aber eine Option zum Testen privater Methoden ist die Verwendung von System.Reflection, um ein Handle für die Methode zu erhalten. Auf diese Weise können Sie private Methoden aufrufen.

Gegeben eine Klasse mit dieser Definition:

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-Klasse mit privaten Zugriffsmechanismen zu generieren, indem Sie mit der rechten Maustaste auf die Methode klicken und "Unit-Tests erstellen ..." auswählen.

14
RobG

Sie können den Zugriff eines Freundes simulieren, wenn sich die Klasse, die das Zugriffsrecht erhält, in einem anderen Paket befindet und die Methoden, die Sie verfügbar machen, als intern oder intern geschützt gekennzeichnet sind. Sie müssen die Assembly ändern, die Sie freigeben möchten, und AssemblyInfo.cs die folgenden Einstellungen 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 je nach Ihren Anforderungen optional.

6
smartmobili