繁体   English   中英

如何拥有只读成员的 C# 接口

[英]How to have C# interface with readonly member

接口不便

我最近发现自己需要一些东西,这在 C# 中应该是非常可能的(我知道它在 C++ 中):几个类需要一个 api 密钥,它绝对必须是一个私有的、不可变的字段(除了在构造函数)。 为了避免代码重复,我想为需要 api 密钥的类创建一个接口。

我会让代码不言自明:

public interface IHasApiKey
{
    protected readonly string _apiKey = String.Empty;
}

问题:

  • 我可以让它成为一个类,因为接口不能实例化成员属性。 但是由于 C# 不允许多重继承,而且我认为这个特性是一种行为而不是一种实现,我不明白为什么它不应该是一个接口。 它可能会与已经有基类的类发生冲突。
  • 我可以将其转换为属性,但是无论可访问性级别如何,如果它是继承的,仍然可以在派生类的方法中进行修改,而我真的想要readonly的行为。 (const,但可以在构造函数中设置)
  • 我发现了属性System.ComponentModel.ReadOnlyAttribute ,但文档非常有限,它看起来不像readonly那样执行,而更像是可以在用户代码中查询的属性。
  • 如果我将其转换为自动属性,则所有派生类都需要指定要指向的私有数据成员,这又意味着重复代码(我首先尝试通过使用此接口来避免这种情况)

为了完整起见,这里是我想象的正确代码在 C++ 中的样子:

class IHasApiKey
{
private:
    std::string _apiKey = "";
protected:
    IHasApiKey(const std::string& apiKey) : _apiKey(apiKey) {}

    // tbo, I'm not quite sure about how to optimally write this one,
    // but the idea is the same: provide protected read access.
    const std::string& GetKey() { return const_cast<std::string&>(_apiKey); }
};

我解释得对吗? 有没有人知道如何优雅地解决这个问题? 非常感谢。

C# 接口没有状态,您不能在接口不可写非只读中声明字段。 事实证明,为了保持状态,您需要类,因此在您的情况下,它应该是基类或具体类...

一种方法是在接口中声明一个 get 属性,这将强制实现该接口的所有类提供 get

public interface IHasApiKey
{
    string ApiKey {get;}
}

和类应该是这样的

public class SomeFoo : IHasApiKey
{
    private readonly string _apiKey;
    public SomeFoo(string apiKey)
    {
        _apiKey = apiKey;
    }

    public string ApiKey => _apiKey;
}

更新 [关闭]

看来我受语言选择的限制。 C# 没有办法完成我想要的。 最好的办法是允许装饰界面的 setter:

public interface IHasApiKey
{
    protected string _apiKey { get; readonly set; }
}

但这可能需要对编译器进行不可能的更改,并且可能会破坏语言设计。 我发现它不太可能被添加。

感谢所有花时间考虑这个问题的人!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM