[英]How to have C# interface with readonly member
I recently found myself in need of something, which should very much be possible in C# (I know it is in C++): Several classes need an api key, which absolutely has to be a private, immutable field (except for being declared in the constructor).我最近发现自己需要一些东西,这在 C# 中应该是非常可能的(我知道它在 C++ 中):几个类需要一个 api 密钥,它绝对必须是一个私有的、不可变的字段(除了在构造函数)。 To avoid code duplication, I wanted to create an interface for classes that need an api key.
为了避免代码重复,我想为需要 api 密钥的类创建一个接口。
I will let the code speak for itself:我会让代码不言自明:
public interface IHasApiKey
{
protected readonly string _apiKey = String.Empty;
}
Problems:问题:
readonly
.readonly
的行为。 (const, but can be set in the constructor) System.ComponentModel.ReadOnlyAttribute
, but documentation is very limited, and it doesn't look like it performs like readonly
, but more like an attribute which can be queried for in user code.System.ComponentModel.ReadOnlyAttribute
,但文档非常有限,它看起来不像readonly
那样执行,而更像是可以在用户代码中查询的属性。 For completeness' sake, here is what I imagine the correct code would look like in C++:为了完整起见,这里是我想象的正确代码在 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); }
};
Do I explain properly?我解释得对吗? And does anyone have an idea of how to solve this elegantly?
有没有人知道如何优雅地解决这个问题? Thanks a lot in advance.
非常感谢。
C# interfaces don't have a state, you can't declare field in interface non writable non read only. C# 接口没有状态,您不能在接口不可写非只读中声明字段。 And it turns out that for keeping a state you need class, so in your case it should be base class, or concrete one...
事实证明,为了保持状态,您需要类,因此在您的情况下,它应该是基类或具体类...
One way to go is to declare a get property in interface, which will force all classes that implement this interface to provide get一种方法是在接口中声明一个 get 属性,这将强制实现该接口的所有类提供 get
public interface IHasApiKey
{
string ApiKey {get;}
}
and classes should look like this和类应该是这样的
public class SomeFoo : IHasApiKey
{
private readonly string _apiKey;
public SomeFoo(string apiKey)
{
_apiKey = apiKey;
}
public string ApiKey => _apiKey;
}
It seems I am limited by my choice of language.看来我受语言选择的限制。 C# has no way of accomplishing what I want.
C# 没有办法完成我想要的。 The best thing would be allow decorating the interface's setter:
最好的办法是允许装饰界面的 setter:
public interface IHasApiKey
{
protected string _apiKey { get; readonly set; }
}
But likely that would require impossible changes to the compiler, and likely break with the language design.但这可能需要对编译器进行不可能的更改,并且可能会破坏语言设计。 I find it unlikely that it will ever be added.
我发现它不太可能被添加。
Thank you everyone who took their time to think about this!感谢所有花时间考虑这个问题的人!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.