【问题标题】:Accessing a private method from another class从另一个类访问私有方法
【发布时间】:2012-08-10 10:46:09
【问题描述】:

我有两个存储库类(RepositoryFactoryBaseRepository)在同一个项目中实现不同的接口。 BaseRepository 类有一个私有方法,现在其他类也需要该方法,具有相同的实现。

我没有复制该方法以使其保持私有,而是考虑一个可能的替代方案,尽管到目前为止我找不到一个好的解决方案,因为根据定义,私有方法仅在其自己的类中具有范围。

使用继承并将方法更改为“受保护”也不是一种选择,因为这两个类在语义上没有链接。由于返回类型为 void,因此我无法使用返回方法结果的公共属性。

【问题讨论】:

  • 他们在同一个项目中; internal 不够吗?
  • 那么,您的意思是RepositoryFactory 构造了BaseRepository 的各种后代,并且您希望工厂在返回之前通过私有方法对对象执行某些操作?
  • 如果你希望它可以被其他类访问,你不能使用private
  • 您在 C# 中寻找 C++ 的 friend 类?抱歉,不存在。正如 Marc 建议的那样,最接近的选择是 internal
  • 很难想象两个不同目的的类可以有相同的功能实现。他们一定有共同点。那么为什么不直接从一个新的抽象基类派生这两个类呢?

标签: c#


【解决方案1】:

您可以使用反射。这是一个例子:

MethodInfo privMethod = objInstance.GetType().GetMethod("PrivateMethodName", BindingFlags.NonPublic | BindingFlags.Instance);
privMethod.Invoke(objInstance, new object[] { methodParameters });

【讨论】:

  • 请注意,如果您经常使用它会极大地影响性能。
【解决方案2】:

用 C# 做你想做的事是不可能的。您可以拥有的最接近的是internal,它使该成员对整个程序集可见。也可以将这两个类设为私有并嵌套在另一个类中,但这并不总是合适的。

从事 C# 工作的 Mads Torgersen 对此表示:

我看到了许多试图解决“类集可访问性”概念的提案。当然,复杂性在于,与现有的可访问性不同,还没有一个自然组(每个人、程序集、派生类、单个类)可以将其绑定,因此即使使用另一个可访问性修饰符,您仍然需要语法(或其他东西)来定义组。

有几种方法可以对其进行切片。我还没有看到明显正确的提案,但我认为问题是相关的,我会与设计团队一起讨论。

(source)

【讨论】:

  • 如何从具有受保护方法的相同基类派生它们?还是让他们实现相同的接口并将方法转换为该接口上的私有扩展方法?
  • @mtijn 你不能真正制作这样的私有扩展方法。 (如果你想出一个方法,请发布!)
  • 我不知道我在想什么,不确实你不能创建这样的扩展方法,你可以创建一个具有内部可见性的扩展方法,但这是一种过于复杂的方法Marc Gravell 已经提出的建议
  • @mtijn:如前所述,使方法受保护并使用继承是不可能的,因为这两个类有不同的用途。他们只需要分享该方法的逻辑。
【解决方案3】:

可以,但是看起来很别扭。这利用了嵌套类能够从包含类访问私有内容的优势。然而,即使某事是可能的,也不意味着你应该去做。如果您只是将修饰符更改为internal,您将获得相同的行为,并且由于这两个类耦合在一起,因此将它们发送到同一个程序集中是有意义的,因此内部修饰符是正确的答案。

public class BaseRepository
{
    public sealed class RepositoryFactory
    {
        public static BaseRepository Create()
        {
            var repo = new BaseRepository();

            repo.MethodRequiredByRepositoryFactory();

            return repo;
        }
    }

    private void MethodRequiredByRepositoryFactory() { }
}

【讨论】:

    【解决方案4】:

    Reference

    可以通过反射实现

    1. 在 Visual Studio 中创建控制台应用程序。
    2. 添加 2 个命名空间
      2.1. System
      2.2. System.Reflection
    3. 现在创建一个类,并在该类中创建一个私有方法,如下所示:

    【讨论】:

    • 欢迎来到 StackOverflow!你能完成你的帖子吗?第 3 步似乎不完整。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    相关资源
    最近更新 更多