从另一个类访问私有方法

8
我有两个仓库类(`RepositoryFactory`和`BaseRepository`),它们实现同一项目中的不同接口。 `BaseRepository` 类具有一个私有方法,在另一个类中也需要该方法,且实现相同。
为了保持它为私有方法而不是复制该方法,我考虑到可能的替代方法,但到目前为止,我找不到一个好的解决方案,因为根据定义,私有方法只在其自己的类中可见。
使用继承并将该方法更改为“protected”也不是一个选项,因为这两个类在语义上没有联系。 我不能使用公共属性来返回该方法的结果,因为返回类型是void。

8
他们在同一个项目中;internal 不就足够了吗? - Marc Gravell
1
如果你想让它可以被其他类访问,就不能使用 private - Umur Kontacı
你在C#中寻找C++的friend类?抱歉,这个不存在。正如Marc所建议的,最接近的替代方案是internal - Cody Gray
1
很难想象两个具有不同目的的类可以拥有相同的函数实现。它们必须有一些共同点。那么为什么不将这两个类都派生自一个新的抽象基类呢? - Yves M.
@CodyGray,你对友元类有一些概念,只是它们如此亲密,以至于它们一个嵌套在另一个里面...你可以说它们是真正的好朋友!(请参见我的答案) - João Angelo
显示剩余3条评论
4个回答

19

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

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

1
请注意,如果您经常使用它,这将极大地影响性能。 - Verbe

9
在C#中,你想要的功能是不可能实现的。最接近的方法是使用internal,这使得成员对整个程序集可见。也可能将两个类设置为私有并嵌套在另一个类中,但这并不总是合适的。
Mads Torgersen是C#的开发人员之一,他对此有以下看法:
引用: 我看到了很多提案试图解决“类集可访问性”的某些概念。当然,与现有的可访问性不同,没有自然的组(所有人、程序集、派生类、单个类)可以绑定到它,因此即使使用另一个可访问性修饰符,你仍然需要语法(或其他东西)来定义这个组。 有几种方法来分割它。我还没有看到一个明显正确的提案,但我认为这个问题是相关的,我会与设计团队讨论这个问题。
(来源链接:source

那么从具有受保护方法的同一基类派生它们如何?或者让它们实现相同的接口,并将该方法转换为该接口上的私有扩展方法呢? - mtijn
@mtijn,你不能像那样真正创建一个私有扩展方法。(如果你能想出一种方法,请务必发布出来!) - Roman Starkov
我不知道自己当时在想什么,确实不能像那样创建扩展方法。你可以创建一个具有内部可见性的扩展方法,但这是 Marc Gravell 已经建议的做法的过于复杂的变体。 - mtijn
@mtijn:正如所说,将该方法设置为受保护的并使用继承是不可能的,因为这两个类有不同的目的。它们只需要共享该方法的逻辑。 - Francesco

4

你可以这样做,但是看起来很奇怪。这是利用嵌套类能够访问包含类中的私有内容。然而,即使某些事情是可能的,也不意味着你应该这样做。如果你只是将修饰符更改为“internal”,那么你就会得到相同的行为,而且由于这两个类是耦合在一起的,所以将它们放在同一个程序集中是有意义的,因此“internal”修饰符是正确的答案。

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

            repo.MethodRequiredByRepositoryFactory();

            return repo;
        }
    }

    private void MethodRequiredByRepositoryFactory() { }
}

0

参考

通过使用反射实现

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

2
欢迎来到StackOverflow!您能完成您的帖子吗?第三步似乎不完整。 - Peter Csala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接