以下不是一个好习惯吗?
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对象发送,以便该方法的用户知道他们可以期望该方法更新或不更新传入的对象。
答案 0 :(得分:5)
我认为你可以忽略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.
答案 1 :(得分:3)
您需要明确地实现其中一个或两个实现:
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
如果您选择不将其标记为显式,则将其作为其他适当类型进行转换时选择的属性。
答案 2 :(得分:2)
我认为在这种情况下你的结构很好。您不希望通过单独的属性显式实现接口,因为您通过不可变接口访问的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;
}
}
答案 3 :(得分:0)
您可以转换变量并告诉编译器您的确切含义:(解决歧义)
MyData myData = new MyData{Data=10};
Console.WriteLine( ((IMyMutableData)(myData)).Data );
答案 4 :(得分:0)
您需要在读写接口上使用带有“new”限定符的组合接口以避免发出尖叫声。此外,您的界面名称很差。更好的名称将是“IReadableData”和“IWritableData”,以及“IReadWriteData”。请注意,虽然“IReadableData”没有提供任何改变数据的方法,但是没有想象力意味着数据是不可变的。如果某些东西是不可改变的,那么每个人都不会改变它;对于MyData类型的对象,情况显然不是这样。