从两个共享某些部分的接口实现一个类
本文关键字:实现 接口 一个 两个 共享 些部 | 更新日期: 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类型的对象,这显然不是这种情况。