在抽象 类 中,在 C# 中正确分配适当的修饰符

Assigning proper modifiers correctly in C# when it comes to abstract classes

我已经 运行 遇到过这种情况很多次,并且 'hacked' 我有办法解决这种情况,但我的理解似乎存在差距。

给定以下代码:

public class Foo
{
    Bar barA = new BarA();

    private void Bat() => barA.Baz();
}

public abstract class Bar
{
    // Obviously this *can't* be private
    private abstract Baz();
}

public class BarA : Bar
{
    public void Run() => Baz();

    // Again this can't be private 
    private override Baz() => DoSomething();
}

(警告:为了简洁起见,我在示例中使用了表达式主体方法。通常我不会这样做,除非有充分的理由。)

现在,在上面的示例中,我的逻辑是 Baz 方法需要由具体 class 定义,但是我希望它私有的原因(是的,我明白为什么它不可能,因为它会完全 invisible/inaccessible 到具体 class),从逻辑上讲,我不希望具体 class 能够调用该方法,只需定义它。

修复代码的方法是创建方法 protected,但是,然后该方法可从具体 class.

中执行

最终,我想要一个 abstract/base class 来处理执行由具体 class 定义的一些代码的内部结构,但是对于具体 class 永远不可用本身到 call/execute。该逻辑有什么缺陷,或者我应该如何正确实施该逻辑。

** 编辑:具体实现 **

例如,假设这是库中插件系统的一部分(我正在创建,另一个开发人员正在实现)。库的另一部分使用派生的 classes 来实现这个抽象 class(假设它是图像处理中的过滤器)。开发人员定义了过滤器的方法,但是抽象 class(基本上处理定义的过滤器提供的唯一处理),是的,合同(接口)是为图像处理器制定的,所以它不会(需要)know/care 无论如何实施。

就像我在评论中所说的那样,您想要做的是有点代码味道。如果您的派生 class 需要定义基础 class 中的某些内容的工作方式,请考虑将接口传递给基础。这样您就不会暴露任何不需要的 public 方法,并使事情更易于测试。你可以这样做。

接口和实现:

public interface IBaz
{
    void Baz();
}

public class BigBaz : IBaz
{
    public void Baz() => Console.WriteLine("Big Baz!");
}

现在您的代码稍作修改:

public abstract class Bar
{
    private readonly IBaz _baz;
    public Bar(IBaz baz)
    {
        _baz = baz;
    }

    public void DoBaz() => _baz.Baz();
}

public class BarA : Bar
{
    //Here I'm passing into the constructor, but you may find it preferable
    //to pass the IBaz directly as a parameter of the DoBaz method
    public BarA() : base(new BigBaz())
    {
    }
}