从两个共享某些部分的接口实现一个类

本文关键字:实现 接口 一个 两个 共享 些部 | 更新日期: 2023-09-27 18:06:35

下面不是一个好的实践吗?

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类的方法时,我想将它作为imimmutable或imimmutable对象发送,以便方法的用户知道他们可以期望方法更新或不更新传入的对象。

从两个共享某些部分的接口实现一个类

我想你可以忽略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.

您需要使其中一个或两个实现显式:

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

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

我认为在这种情况下你的结构是好的。您不希望通过单独的属性显式地实现接口,因为这样您通过不可变接口访问的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;
    }
}

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

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

您需要一个在读写接口上带有"new"限定符的组合接口,以避免出现问题。此外,接口的命名也很糟糕。更好的名字应该是"IReadableData"answers"IWritableData"answers"IReadWriteData"。请注意,虽然"IReadableData"没有提供任何改变数据的方法,但这并不意味着数据是不可变的。如果某样东西是不可变的,它不会被任何人改变;对于MyData类型的对象,这显然不是这种情况。