Zac Shepherd
Zac Shepherd

Reputation: 103

Private-ish method?

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

Answers (7)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

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

Ronan Thibaudau
Ronan Thibaudau

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

Marek Woźniak
Marek Woźniak

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

Vitaliy Fedorchenko
Vitaliy Fedorchenko

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

Sweeper
Sweeper

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

Brian Towers
Brian Towers

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

Neel
Neel

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

Related Questions