如何强制实现私有方法,因为接口方法只能是公共的?

5

接口可以用来强制实现方法,但是这些方法需要是公共的。

那么如果我想强制实现私有方法呢?

更新:这不是为了防止调用,而是确保私有方法已经被实现。

所以我不想仅仅使用接口,我想对团队施加一些编码风格的要求。


2
这没有意义。如果你想防止除了你自己的类之外的任何人调用该方法,那么只需从接口中删除该方法。然后编写一个私有方法。 - Hans Passant
这不是为了防止调用,而是为了确保私有方法已经被实现。 - user310291
1
唯一能调用私有方法的是你的代码...从你的类中调用你所说的私有方法...如果它还没有被实现,它就不能编译?!? - forsvarir
1
为什么你关心一个私有方法是否已经被实现?我认为你不想让接口做你试图做的事情。 - stephenbayer
1
不一定是我的代码:可能是其他人的代码,但你希望他遵守某些编码风格。 - user310291
6个回答

10

接口总是公共的定义。强制实现受保护的方法(对外部私有但可由派生类访问)的唯一方法是通过子类化定义该方法的抽象类:

public abstract class A
{
    protected abstract void Foo();
}

public class B : A
{
    protected override void Foo() { }
}

如果您正在尝试在B中更改Foo的访问修饰符,或者忘记为B提供Foo()的实现,则上述代码将会出错。

编辑:

我相信使用一个嵌套类可以做到接近你所想要的:这将允许使用外部类的私有字段,并同时强制执行接口的实现,而技术上该类在任何其他地方都不可见:

public interface IFooWorker
{
    void DoWork();
    int CalculateSomething();
}

public class Foo
{
    private FooWorker _worker;
    private int _currentValue;
    private string _workStatement;


    public Foo()
    {
        _worker = new FooWorker(this);
    }

    private class FooWorker : IFooWorker
    {
        private Foo _outer;
        public FooWorker(Foo foo)
        {
            _outer = foo;
        }

        public void DoWork()
        {
            _outer._currentValue = CalculateSomething();
            _outer._workStatement = "I did work";
        }

        public int CalculateSomething()
        {
            return 42;
        }
    }

}

如果你的类已经继承了一个具体类(例如UserControl),该怎么办? - user310291
@user310291:你不能这样做 - 一种替代方案是使用组合而不是继承,但这可能不是你想要的,因为你仍然只能访问所访问类的公共方法。 - BrokenGlass
那么也许可以使用这个?http://stackoverflow.com/questions/5766166/can-design-by-contract-allow-me-to-enforce-private-methods - user310291
@user,您可以插入一个中间层类。例如,class Foo 是您无法修改的某个地方。您可以创建 public abstract class MyFoo : Foo 来添加一个抽象受保护成员,然后更具体的类从 MyFoo 继承并提供实现。 - Anthony Pegram

4
为什么要通过接口来规定私有方法?每个类应该是一个黑盒子,接口只定义对该类的公共访问,并且不应关心该类的私有内部细节,只需确保公共方法以智能方式工作即可。所以,我的意思是根本不要考虑这个问题,因为这个概念完全违背了语言特性所尝试实现的目标。

我并不想单纯地使用接口。我想向团队施加一些编码风格。 - user310291

2
实际上,私有方法对于包含它的类之外的代码来说是不存在的。它可以通过反射找到,但是私有作用域的整个意义并不属于对象API的一部分。私有成员明确不属于对象契约的一部分,它是被封装在其中的东西。
您为什么要试图强制其他开发人员“遵循编码风格”到那种细粒度?目的或期望结果是什么?
从另一个角度来看,您已经多次表示要“确保实现该方法”或类似的东西。
如果您想针对特定方法签名采取行动,并确保它已实现,则可以使用委托 / Func / Action,并让外部代码注入其相应的实现。您的内部代码可以检查是否已提供并在其存在时进行调用。由于您已提供了对它的引用,因此您知道存在一个处理调用的对应方法...即您知道某个地方已经实现了相应的方法。
如果您的情况比较简单,并且您正在从内部逻辑冒泡到外部逻辑,则只需使用事件即可。创建您的事件参数以包含您需要提供给附加处理程序的任何内容,使用通用事件处理程序,在您的内部逻辑中声明一个事件,在需要将控件传递给外部逻辑的已实现方法时引发该事件,如果不为空,则外部逻辑挂钩事件并根据其使用情况执行任何适当的操作。事件模型是契约性的,在.NET中非常自然,在很多地方都被广泛使用,并且容易使用,许多开发人员非常熟悉该模式,并知道如何将其插入其中。
您所坚持的“私有”方法契约对您来说不太可能产生成果,并且与面向对象设计相违反,依我之见。
祝好运!

1

它不会是“私有的”,但您仍然可以使用显式接口实现来模拟它。

请参见:http://msdn.microsoft.com/en-us/library/ms173157.aspx

但是,没有任何东西可以阻止某人通过向上转换为接口类型直接调用您的方法。再说了,私有方法是实现细节:它们不属于接口。


我真的不想公开,我想确保私有方法被实现了。 - user310291
也许你需要创建一个抽象类,并将该方法设置为受保护的。 - Etienne de Martel

1

按照定义,接口是一组公共方法。也许你需要一个抽象类。


0

这是没有意义的,因为在接口中声明的私有方法无法被调用。


我不想使用接口,我想确保私有方法存在。 - user310291
一个无法被调用的方法有什么用处呢?也许发布一个具体的例子会更有意义。我想我不是唯一感到困惑的人。 - Axel

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