私有方法?

Private-ish method?

在我的项目中,我经常希望有一个私有的方法(或者函数,如果你愿意的话),但是我也想从另一个 class 访问它。有这种可能吗?

澄清一下,此方法可以从 ClassA 访问,它自己的 class 但不能从任何其他访问。

无论你问什么,在 C# 中都是不可能的。我的意思是你不能只允许一个 class 使用私有方法。您所能做的就是使用 internal,它只允许一个程序集的 classes 访问您的方法,或者使用 protected,它可以在其 class 中访问,并通过派生 class 实例!

除此之外,对于您的要求没有任何经验法则,但您可以进行一些修改,如下所示:

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

在 class A 中使用来自 class B 的方法的一个有点肮脏的技巧是使方法受保护而不是私有,并从 B 派生 A。

另一种可能更好的方法是将方法设置为内部方法而不是私有方法,然后将 class A 和 B 放在同一个程序集中。

如果适合您的 OOP 结构,您可以保护此方法:

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

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

还有很多其他方法可以做到这一点。

但是,总的来说,这听起来像是对访问修饰符的错误看法。
如果你只想从一个地方调用你的方法,那么就从一个地方调用它。
应该从另一个 class 调用此方法这一事实使他在逻辑和体系结构上 public。

我能想到的最好的方法就是这个。

在C# 5中,添加了一组调用者信息属性,即[System.Runtime.CompilerServices.CallerMemberName][System.Runtime.CompilerServices.CallerFilePath][System.Runtime.CompilerServices.CallerLineNumber]。我们可以使用 CallerFilePathAttribute 来查看调用者是否来自特定的 .cs 文件。

通常,一个文件只会包含一个 class 或结构。例如,ClassA 定义在 ClassA.cs 中。您可以在方法中检查调用者文件名是否匹配ClassA.cs

所以像这样修改你的方法的参数:

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

在方法中,检查callerFilePath是否匹配ClassA的文件路径。如果没有,则抛出一个异常,说明该方法只能从 ClassA!

访问

另一种控制成员访问的简单方法是使用委托。 假设您有一个私有方法:

class SecureMethod {
    private void DoSomething() { }
}

您可以通过向此方法注入委托来提供对此方法的访问:

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

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

我正在向您展示如何做到这一点,但这些都是非常糟糕的做法:

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

在代码中:

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

但是更好的方法是在方法的类 A 中使用类 B 的对象。在 google 中搜索 策略模式 或使用 继承

有很多方法可以做到这一点,直到你的最后一个陈述是 "and ONLY that class",我只能想到一种方法来做到这一点,那就是将 classes 放在像这样的程序集:

程序集 A 仅包含 class A 以及您要声明为内部的方法

程序集 B 声明为友好程序集:https://msdn.microsoft.com/en-us/library/0tke9fxk.aspx 并包含调用 A 的代码(它可以说它是内部程序集,就像在同一个程序集中一样,因为它是友好程序集)

链接到 A 、 B 或两者的任何其他程序集都无法调用 class A 上的方法,因为它是内部方法。