简体   繁体   English

在C#中实现只读(不可变)对象接口

[英]Implement a readonly (immutable) object interface in 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. 举个例子,如果我使用的是C ++,我只会返回一个const对象。
  • In C#, if I could achieve this with interfaces, I would just implement a read-only interface and use it everywhere. 在C#中,如果我可以通过接口实现这一点,我只需实现一个只读接口并在任何地方使用它。 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#? 那么,我怎样才能在C#中实现我的目标?

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. 它不是一个100%完美的解决方案(您仍然可以将对象转换为修改界面),但在大多数情况下,它会阻止任何人意外调用修改方法。

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. 此外,并非所有.NET语言都以相同的方式使用运算符重载。 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. 我将实现只读接口并删除运算符重载要求。

您可以通过对象中的状态实现只读行为,并在调用修改方法时抛出异常?

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): 就像在基本抽象类(readonly接口)中一样:

protected double accuracy;
public double Accuracy { get { return accuracy; } }

In the derived class: 在派生类中:

public new double Accuracy
{
    get { return accuracy; }
    set { accuracy = value; }
}

Of course, ugly with the "new" keyword, but in this case it will do for me. 当然,丑陋的“新”关键字,但在这种情况下,它将为我做。

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

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