Reputation: 103
Within my projects I often want to have a method (or function if you prefer) that is private, however I also want to access it from ONE other class. Is this a possibility?
To clarify, this method can be accessed from ClassA
, its own class but not any other.
Upvotes: 5
Views: 194
Reputation: 34189
You can make this method protected, if it suits your OOP structure:
public class A
{
protected void Test()
{
Console.WriteLine("I can only be called from B");
}
}
public class B : A
{
public void Pub()
{
Test();
}
}
And there many other ways to do this.
However, in general, it sounds like a wrong look at access modifiers.
If you want to only call your method from exactly one place, then just call it from exactly one place.
The fact that this method should be called from another class, makes him public, logically and architecturally.
Upvotes: 2
Reputation: 3603
There are plenty of ways to do this untill your last statement that is "and ONLY that class", i can only think of 1 way to do that and it is to have the classes laid out in assemblies as such as such:
Assembly A only contains class A with the method you want declared as internal
Assembly B declared as a friendly assembly : https://msdn.microsoft.com/en-us/library/0tke9fxk.aspx and contains code to call A (it can as to it it is internal as if in the same assembly as it is a friend assembly)
No other assembly linked to A , B or both will be able to call the method on class A as it is internal.
Upvotes: 2
Reputation: 1776
I'm showing you how do to this, but these are very bad practices:
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();
but better way is to use object of ClassB in method's classA. Search google for strategy pattern or use inheritance.
Upvotes: 1
Reputation: 9235
Another simple way to control member access is using delegates. Let's assume you have a private method:
class SecureMethod {
private void DoSomething() { }
}
You can provide access to this method by injecting delegate to this method:
class ClassA {
public ClassA(Action secureMethod) { }
}
SecureMethod objWithSecureMethod;
var a = new ClassA( objWithSecureMethod.DoSomething );
Upvotes: 1
Reputation: 270980
The best way that I can think of is this.
In C# 5, a set of caller information attributes were added, namely [System.Runtime.CompilerServices.CallerMemberName]
, [System.Runtime.CompilerServices.CallerFilePath]
, and [System.Runtime.CompilerServices.CallerLineNumber]
. We can use the CallerFilePathAttribute
to see whether the caller comes from a particular .cs
file.
Usually, one file will only contain one class or struct. For example, ClassA
is defined in ClassA.cs
. You can check if the caller file name matches ClassA.cs
in the method.
So modify your method's parameters like this:
([CallerFilePath] string callerFilePath = "" /*Other parameters*/)
In the method, check if the callerFilePath
matches the file path of ClassA
. If it does not, throw an exception saying that the method can only be accessed from ClassA
!
Upvotes: 2
Reputation: 350
One slightly dirty trick to use a method from class B in class A is to make the method protected rather than private and derive A from B.
Another possibility, probably better, is to make the method internal rather than private and then put class A and B in the same assembly.
Upvotes: 0
Reputation: 11721
Whatever you are asking is not possible in C#. I mean you can not allow only one class to use private method. All you can do is to use internal
which allows classes of just one assembly to access your methods or protected
which is accessible within its class and by derived class instances!
Apart from that There is not any thumb rule for what you are asking but you can do some hack as shown below:
MethodInfo privateMethod = instance.GetType().GetMethod("NameOfPrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance);
privateMethod.Invoke(instance, new object[] { methodParameters });
Upvotes: 0