2015-12-25 4 views
5

Innerhalb meiner Projekte möchte ich oft eine Methode (oder Funktion, wenn Sie bevorzugen), die privat ist, aber ich möchte auch von einer anderen Klasse zugreifen. Ist das eine Möglichkeit?Private-ish-Methode?

Um zu klären, kann diese Methode von ClassA zugegriffen werden, eine eigene Klasse, aber keine andere.

+2

Wenn Sie beiden Klassen in eine Assembly setzen gewidmet nur diese beiden Klassen können Sie 'internal' verwenden. Aber ... Sie sollten vielleicht überdenken, warum Sie das tun müssen. –

+0

Was ist der Grund für diese Art von Design? – dotctor

+0

Mögliche doppelte: http://stackoverflow.com/questions/203616/why-does-c-sharp-not-provide-the-c-style-friend-keyword –

Antwort

2

Es gibt viele Möglichkeiten, dies zu tun, bis Ihre letzte Aussage, "und nur diese Klasse", kann ich nur eine Möglichkeit, dies zu tun, und es ist die Klassen in Baugruppen als solche als solche ausgelegt haben :

Assembly A enthält nur Klasse A mit der Methode, die Sie als interne erklärt wollen

Assembly B als eine freundliche Versammlung erklärt: https://msdn.microsoft.com/en-us/library/0tke9fxk.aspx und enthält Code A zu nennen (es wie es kann es intern ist, als ob in die gleiche Anordnung, wie es ist ein Freund assembly)

keine andere A, B verbunden Montage oder beide werden in der Lage sein, die Methode für die Klasse A aufzurufen, da sie intern ist.

+0

Ich denke, das ist der einzige Weg, es zu tun. – dotctor

1

Was auch immer Sie fragen, ist in C# nicht möglich. Ich meine, Sie können nicht nur einer Klasse erlauben, private Methode zu verwenden. Alles, was Sie tun können, ist internal, die Klassen von nur einer Assembly Zugriff auf Ihre Methoden oder protected ermöglicht, die innerhalb seiner Klasse und von abgeleiteten Klassen Instanzen zugänglich ist!

von Apart, dass Es gibt keine Faustregel für das, was Sie fragen, aber Sie können etwas Hack tun, wie unten gezeigt:

MethodInfo privateMethod = instance.GetType().GetMethod("NameOfPrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance); 
privateMethod.Invoke(instance, new object[] { methodParameters }); 
0

Ein etwas schmutziger Trick eine Methode aus der Klasse B zu verwenden, in A-Klasse um die Methode eher geschützt als privat zu machen und A von B abzuleiten.

Eine andere Möglichkeit, wahrscheinlich besser, ist, die Methode intern statt privat zu machen und dann Klasse A und B in dieselbe Baugruppe zu setzen.

2

Sie können diese Methode geschützt machen, wenn es Ihre OOP Struktur passt:

public class A 
{ 
    protected void Test() 
    { 
     Console.WriteLine("I can only be called from B"); 
    } 
} 

public class B : A 
{ 
    public void Pub() 
    { 
     Test(); 
    } 
} 

Und es gibt viele andere Möglichkeiten, dies zu tun.

Im Allgemeinen klingt es jedoch nach einem falschen Blick auf Zugriffsmodifizierer.
Wenn Sie Ihre Methode nur an genau einem Ort aufrufen möchten, rufen Sie sie einfach von genau einem Ort aus an.
Die Tatsache, dass diese Methode von einer anderen Klasse aufgerufen werden sollte, macht ihn öffentlich, logisch und architektonisch.

+0

Jede Klasse, die von A abgeleitet ist, kann auf die Testmethode zugreifen. OP will "aber ich möchte auch von einer anderen Klasse darauf zugreifen, und diese andere Klasse nur!" – dotctor

2

Der beste Weg, an den ich denken kann, ist dies.

In C# 5 wurde eine Reihe von Informationen zu Anruferinformationen hinzugefügt, nämlich [System.Runtime.CompilerServices.CallerMemberName], [System.Runtime.CompilerServices.CallerFilePath] und [System.Runtime.CompilerServices.CallerLineNumber]. Wir können die CallerFilePathAttribute verwenden, um zu sehen, ob der Aufrufer aus einer bestimmten .cs Datei stammt.

Normalerweise enthält eine Datei nur eine Klasse oder Struktur. Zum Beispiel ist ClassA in ClassA.cs definiert. Sie können überprüfen, ob der Name der Anruferdatei in der Methode mit ClassA.cs übereinstimmt.

So Ihre Methode der Parameter wie folgt ändern:

([CallerFilePath] string callerFilePath = "" /*Other parameters*/) 

In dem Verfahren prüfen, ob die callerFilePath den Dateipfad von ClassA übereinstimmt. Wenn dies nicht der Fall ist, wird eine Ausnahme ausgelöst, die besagt, dass auf die Methode nur von ClassA zugegriffen werden kann!

+0

Diese Überprüfung wird nur in Runtime durchgeführt. – dotctor

+0

Ja ... Ich weiß. Sie können die Methode jedoch nicht in einer anderen Klasse als ClassA verwenden. So erfüllt es die Anforderungen! @ dotctor – Sweeper

1

Eine weitere einfache Möglichkeit, den Mitgliederzugriff zu steuern, besteht in der Verwendung von Delegaten. Nehmen wir an, Sie eine private Methode haben:

class SecureMethod { 
    private void DoSomething() { } 
} 

Sie den Zugriff auf diese Methode zur Verfügung stellen kann, um dieses Verfahren durch die Injektion von Delegierten:

class ClassA { 
public ClassA(Action secureMethod) { } 
} 

SecureMethod objWithSecureMethod; 
var a = new ClassA(objWithSecureMethod.DoSomething); 
1

ich Ihnen zeigen, wie man dies tun, aber diese sind sehr schlechte Praktiken:

public class A 
{ 
    private void CanOnlyCallMethodInClassB(); 
    public static void SetHandlerCanOnlyCallMethodInClassB(ClassB b) 
    { 
     b.MethodFromClassA = CanOnlyCallMethodInClassB; 
    } 
} 
public class B 
{ 
    public Action MethodFromClassA { get; set; } 
} 

in Code:

var b = new B(); 
A.SetHandlerCanOnlyCallMethodInClassB(b); 
b.MethodFromClassA(); 

aber besser Weise ist Gegenstand von ClassB in classA Methode zu verwenden. Google-Suche nach Strategie Muster oder verwenden Erbe.