在 C# 中实现只读(不可变)对象接口
我的目标是确保在大多数情况下通过“只读接口”使用对象,该“只读接口”是完整接口的子集。
- 举个例子,如果我使用 C++,我只会返回一个 const 对象。
- 在 C# 中,如果我可以通过接口实现这一点,我只需实现一个只读接口并在任何地方使用它。 但是,我需要运算符重载,这对于接口来说是不允许的。 这就是为什么我必须使用抽象基类。
- 但是,如果我定义一个抽象基类,则不允许我更改派生类型中的可访问性。
那么,我怎样才能在 C# 中实现我的目标呢?
My goal is to make sure that in most scenarios objects are used via a "read-only interface" that is a subset of the full interface.
- As an example, if I were using C++, I would just return a
const
object. - In C#, if I could achieve this with interfaces, I would just implement a read-only interface and use it everywhere. However, I need operator overloading, which is not allowed for interfaces. That's why I have to use an abstract base class.
- But if I define an abstract base class, I am not allowed to change accessibility in the derived type.
So, how can I achieve my goal in C#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果将写入操作放在接口中,然后在抽象基类上显式实现,效果如何? 这不是一个 100% 完美的解决方案(您仍然可以将对象强制转换为修改接口),但在大多数情况下,它可以防止任何人意外调用修改方法。
How about if you placed your write operations in an interface and then implement in explicitly on the abstract base class? It would not be a 100% perfect solution (you could still cast the object to the modification interface), but for most part it would prevent anyone from accidentally calling the modifying methods.
您真的需要运算符重载吗? 我们在这里讨论的是语法糖。 此外,并非所有 .NET 语言都以相同的方式利用运算符重载。 因此,如果您使用运算符重载,则可以有效地使代码特定于语言。
我将实现只读接口并放弃运算符重载要求。
Do you really need operator overloading? We are talking about syntactic sugar here. Also, not all .NET languages utilize operator overloading in the same way. So, if you use operator overloading, you are effectively making your code language-specific.
I would implement the read-only interface and drop the operator overloading requirement.
您可以通过对象中的状态实现只读行为,并在调用修改方法时抛出异常?
You could implement the readonly behaviour via state in the object, and throw an exception if a modifying method is called?
如果有人对我所做的感兴趣,我最终选择了抽象类而不是接口,并且我确实隐藏了派生类中的方法以获得正确的访问器:
就像在基抽象类(只读接口)中
:派生类:
当然,使用“new”关键字很难看,但在这种情况下它对我来说就足够了。
If anyone is interested in what I did, I finally went for an abstract class instead of interface, and I did hide the method in the derived class to get the right accessors:
Like, in the base abstract class (readonly interface):
In the derived class:
Of course, ugly with the "new" keyword, but in this case it will do for me.