【问题标题】:Implement a readonly (immutable) object interface in C#在 C# 中实现只读(不可变)对象接口
【发布时间】:2010-09-27 05:57:14
【问题描述】:

我的目标是确保在大多数情况下通过“只读接口”使用对象,该接口是完整接口的子集。

  • 例如,如果我使用 C++,我将只返回一个 const 对象。
  • 在 C# 中,如果我可以通过接口实现这一点,我将只实现一个只读接口并在任何地方使用它。但是,我需要运算符重载,这对于接口是不允许的。这就是我必须使用抽象基类的原因。
  • 但是,如果我定义了一个抽象基类,则不允许我更改派生类型中的可访问性。

那么,如何在 C# 中实现我的目标?

【问题讨论】:

    标签: c# interface abstract-class immutability readonly


    【解决方案1】:

    你真的需要运算符重载吗?我们在这里谈论语法糖。此外,并非所有 .NET 语言都以相同的方式使用运算符重载。因此,如果您使用运算符重载,您实际上是在使您的代码特定于语言。

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

    【讨论】:

    • @Chris - 在不同的应用程序中我完全同意 :) 我几乎完成了。在这个(计算)中 - 放弃它是非常不幸的,它实际上比放弃只读要求更不幸......
    • ReadOnly 或 const,对于参数约束,我也希望在 C# 中看到。创建只读接口并不是最好的解决方案。但有时你只需要生活在你正在使用的语言中。
    【解决方案2】:

    如果有人对我的工作感兴趣,我最终选择了一个抽象类而不是接口,并且我确实将方法隐藏在派生类中以获得正确的访问器:

    比如,在基础抽象类(只读接口)中:

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

    在派生类中:

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

    当然,“new”关键字很难看,但在这种情况下,它会为我做。

    【讨论】:

      【解决方案3】:

      如果你把你的写操作放在一个接口中,然后在抽象基类上显式地实现呢?这不是一个 100% 完美的解决方案(您仍然可以将对象强制转换为修改接口),但在大多数情况下,它可以防止任何人意外调用修改方法。

      【讨论】:

      • @Vilx - 我喜欢你的建议,但我决定不去做,因为 J. Richter 建议尽可能避免显式接口实现......特别是因为我会这样做很多这样的演员,即使我是派生类型。
      • 为什么不做一个同时包含读写方法的接口呢?隐式实现读取方法,并显式编写方法。然后你只需要强制转换一次就可以得到一个可读写的对象。
      【解决方案4】:

      你可以通过对象中的状态实现只读行为,如果调用修改方法则抛出异常?

      【讨论】:

      • 我在类中做了类似的事情,我同时提供了ReadOnly 属性和Save 方法。如果类的一个实例使得ReadOnlytrue,则对Save 的调用将引发InvalidOperationException。也就是说,这种情况没有您描述的那么严格。这种类的实例可以被其他方法和属性改变。但是,该实例无法保存(例如,保存到磁盘)。
      猜你喜欢
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      • 2018-10-26
      • 2011-04-17
      • 1970-01-01
      • 2015-05-13
      • 2018-05-21
      • 1970-01-01
      相关资源
      最近更新 更多