【问题标题】:Implementing a class from 2 interfaces that share some parts从共享某些部分的 2 个接口实现一个类
【发布时间】:2011-11-03 21:42:52
【问题描述】:

以下不是一个好的做法吗?

public interface IMyImmutableData
{
    int Data { get;}
}

public interface IMyMutableData
{
    int Data { set;get;}//implements both get and set
}

public class MyData : IMyImmutableData, IMyMutableData
{
    public int Data{get;set;} //implements both IMyImmutableData, IMyMutableData
}

void Main()
{
    MyData myData = new MyData{Data=10};
    Console.WriteLine(myData.Data);
}

我问的原因是 resharper 给了我以下警告:“通过此接口访问时可能存在歧义”

我想要执行上述操作的原因是,当我创建使用 MyData 类的方法时,我想将其作为 IMyMutable 或 IMyImmutable 对象发送,以便该方法的用户知道他们可以期望该方法更新或不更新传入的对象。

【问题讨论】:

  • 作为一个注释,我认为IMyReadOnlyDataIMyImmutableData 具有更好的含义,因为对象是可变的。

标签: c# oop interface


【解决方案1】:

我认为您可以忽略 resharper 的警告,因为歧义是故意的。

但是,通常包装类用于提供对某些内容的只读访问,这样就无法将其强制转换为提供更多功能的任何内容。

public class MyReadonlyData : IMyReadonlyData {
    private MyData instance;

    public int Data {
        get {
            return instance.Data;
        }
    }

    public MyReadonlyData( MyData mydata ) {
        instance = mydata;
    }
}
// no access to original object or setters, period.

【讨论】:

  • 虽然,我接受了 dlev 的回答,但我喜欢你的解决方案,并将重新设计我的项目以使用你的想法。它更优雅(imo)。
【解决方案2】:

您需要明确其中一个或两个实现:

public int IMyImmutableData.Data { get; }
public int IMyMutableData.Data { get; set; }

当您将一个标记为显式时,只有在明确转换为该类型时才能访问它:

MyData obj = new MyData();
obj.Data; // Doesnt exist
(obj as IMyImmutableData).Data // Exists, specifically cast as this interface

如果您选择不将一个标记为显式,则它将是在转换为其他适当类型时选择的属性。

【讨论】:

【解决方案3】:

我认为在这种情况下你的结构很好。您不想通过单独的属性显式实现接口,因为您通过不可变接口访问的 Data 实际上将与可变接口的 不同

此外,您的实际代码可能更复杂,因为在这种情况下没有歧义:您通过对象本身访问Data,因此无需考虑接口。

具有显式接口实现的一种解决方案是使用公共支持字段,而不是自动属性:

private int _data;
public int IMyImmutableData.Data
{
    get
    {
        return this._data;
    }
}

public int IMyMutableData.Data
{
    get
    {
        return this._data;
    }
    set
    {
        this._data = value;
    }
}

【讨论】:

  • 我将此答案标记为“the”答案,因为它离我的答案很近。但我认为,我会使用 Joel B Fant 的解决方案,因为它更优雅。
【解决方案4】:

您可以转换变量并告诉编译器您的确切含义:(解决歧义)

MyData myData = new MyData{Data=10};
Console.WriteLine( ((IMyMutableData)(myData)).Data );

【讨论】:

    【解决方案5】:

    您需要一个在读写接口上带有“新”限定符的组合接口,以避免出现问题。此外,您的接口命名不佳。更好的名称应该是“IReadableData”、“IWritableData”和“IReadWriteData”。请注意,虽然“IReadableData”没有提供任何改变数据的方法,但无论如何想象都暗示数据是不可变的。如果某些东西是不可变的,那么它不会被任何人改变; MyData 类型的对象显然不是这种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-06
      • 1970-01-01
      • 2018-05-26
      • 2023-04-05
      相关资源
      最近更新 更多