接口中的私有成员

private members in interface

是否可以在 .NET 的接口中创建私有成员?我听说现在可以了,但我的 IDE 拒绝了它:

public interface IAnimal
{
    void SetDefaultName(string name)
    {
        ChangeName(name);
    }

    private string defaultName = "NoName";

    private void ChangeName(string name)
    {
        defaultName = name;
    }
    void Breath()
    {
        Console.WriteLine($"Default - I'm {defaultName}. <Breathing sounds>");
    }

    void Sound();
}

是的!现在您可以在 C# 8.0 中使用,但它必须是静态成员。像这样:

public interface IAnimal
{
    static void SetDefaultName(string name)
    {
        ChangeName(name);
    }

    private static string defaultName = "NoName";

    private static void ChangeName(string name)
    {
        defaultName = name;
    }
    void Breath()
    {
        Console.WriteLine($"Default - I'm {defaultName}. <Breathing sounds>");
    }

    void Sound();
}

但您需要记住,静态字段将在整个应用程序中共享。更改 defaultName 将导致在您使用 IAnimal

的每个地方更改它

private 方法曾经在接口中被禁止,因为接口应该是 contracts。它们是“this class 具有以下方法和属性”的保证。为什么保证 class 具有 private 方法会有用?它没有用,因为没有其他人可以调用它!

在 C# 8 中,这发生了变化。您现在可以指定 private 接口默认方法。请注意,它必须是默认方法,而不是没有实现的方法。这是 docs 说明的事实:

The syntax for an interface is relaxed to permit modifiers on its members. The following are permitted: private, protected, internal, public, virtual, abstract, sealed, static, extern, and partial.

...

It is an error for a private or sealed function member of an interface to have no body.

这是文档中的引述,解释了为什么允许这样做:

Static and private methods permit useful refactoring and organization of code used to implement the interface's public API.

实际问题应该是:我应该做(或能够做)还是不做?

接口的全部思想是提供抽象。

私有成员通常是代码的使用者不应该关心或知道它们存在的实现细节,因此它们不属于您的抽象层(接口)

接口是消费者将与你service/component彻底交互的外观,它应该只包含消费者将调用的方法,这就是为什么最初接口应该只有 public 修饰符

更不用说将这些成员放在接口中会强制它的每个实现都实现这些成员,即使它们不需要它

在我看来,C# 更改接口并使它们允许实现的唯一原因是弥补语言对多重 class 继承的支持不足,但这确实意味着您应该错过使用您的接口,例如

是的,在 C# 8.0 中,您可以拥有 public、私有成员和受保护成员。

例如以下作品:

public interface ITest
{
   private SomeEnum EnumTy { get => SomeEnum.Value1; }
}

如果 class 实现接口并尝试访问变量,他们将收到错误。

public class TestImpl : ITest
{
 ITest.EnumTy = SomeEnum.Value2; // gives an error
}

成员也可以被保护。作为一个建议,在方法之前使用 public 表示更好的可读性是好的(即使 public 是默认值)。

一篇好文章在这里:

https://jeremybytes.blogspot.com/2019/11/c-8-interfaces-public-private-and.html