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

时间:2022-01-24 05:40:49

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. However, I need operator overloading, which is not allowed for interfaces. That's why I have to use an abstract base class.
  • 在C#中,如果我可以通过接口实现这一点,我只需实现一个只读接口并在任何地方使用它。但是,我需要运算符重载,这是接口不允许的。这就是我必须使用抽象基类的原因。

  • 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#中实现我的目标?

4 个解决方案

#1


4  

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

#2


3  

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.

你真的需要操作员重载吗?我们在这里讨论语法糖。此外,并非所有.NET语言都以相同的方式使用运算符重载。因此,如果使用运算符重载,则有效地使您的代码语言特定。

I would implement the read-only interface and drop the operator overloading requirement.

我将实现只读接口并删除运算符重载要求。

#3


2  

You could implement the readonly behaviour via state in the object, and throw an exception if a modifying method is called?

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

#4


1  

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.

当然,丑陋的“新”关键字,但在这种情况下,它将为我做。

#1


4  

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

#2


3  

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.

你真的需要操作员重载吗?我们在这里讨论语法糖。此外,并非所有.NET语言都以相同的方式使用运算符重载。因此,如果使用运算符重载,则有效地使您的代码语言特定。

I would implement the read-only interface and drop the operator overloading requirement.

我将实现只读接口并删除运算符重载要求。

#3


2  

You could implement the readonly behaviour via state in the object, and throw an exception if a modifying method is called?

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

#4


1  

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.

当然,丑陋的“新”关键字,但在这种情况下,它将为我做。

相关文章