Issue
Interface inconvenience
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). To avoid code duplication, I wanted to create an interface for classes that need an api key.
I will let the code speak for itself:
public interface IHasApiKey
{
protected readonly string _apiKey = String.Empty;
}
Problems:
- I could let it be a class instead, since interfaces cannot instantiate member attributes. But since C# does not allow multiple inheritance, and since I consider this feature a behaviour rather than an implementation, I can't see why it shouldn't be an interface. And it might clash with classes which already have a base class.
- I could convert it into a property, but no matter the accessibility level, if it is inherited, it can still be modified in methods of derived classes, whereas I really want the behaviour of
readonly
. (const, but can be set in the constructor) - I discovered the attribute
System.ComponentModel.ReadOnlyAttribute
, but documentation is very limited, and it doesn't look like it performs likereadonly
, but more like an attribute which can be queried for in user code. - If I convert it to an auto-property, then all derived classes need to specify a private data member to point to, which again means duplicate code (which I try to avoid by having this interface in the first place)
For completeness' sake, here is what I imagine the correct code would look like in 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.
Solution
Update [Closed]
It seems I am limited by my choice of language. C# has no way of accomplishing what I want. The best thing would be allow decorating the interface's 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!
Answered By - alexpanter Answer Checked By - Senaida (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.