Implement a class of 2 interfaces that share some parts

Is the following practice wrong?

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); } 

I ask that resharper gives me the following warning: "Possible ambiguity when accessing this interface"

The reason I want to do this is because when I create methods that use the MyData class, I would like to send it either as IMyMutable or IMyImmutable objects, so that the users of the method know that they can expect the method update or not update the transferred object.

+4
source share
5 answers

I think that in this case your structure is beautiful. You do not want to explicitly implement interfaces using separate properties, because then access to Data via an immutable interface will be different from that used for a mutable interface.

In addition, your actual code is most likely more complex, because in this case there is no ambiguity: you access the Data through the object itself, so interfaces should not be considered.

One solution with an explicit implementation of the interface would be to use a common support field, rather than an automatic property:

 private int _data; public int IMyImmutableData.Data { get { return this._data; } } public int IMyMutableData.Data { get { return this._data; } set { this._data = value; } } 
+2
source

You need to make one or both versions explicit:

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

When you mark one as explicit, access to it can only be available with a specific cast as this type:

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

If you decide not to mark one as explicit, this will be the property selected when used as other appropriate types.

+3
source

I think you can ignore the resharper warning as ambiguity is intentional.

However, usually a wrapper class is used to provide read-only access, so it cannot be applied to anything that provides more functionality.

 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. 
+3
source

You can specify a variable and tell the compiler exactly what you mean: (allow ambiguity)

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

You need a combined interface with a “new” qualifier on the read and write interface to avoid squocking. In addition, your interfaces are poorly named. Better names will be like "IReadableData" and "IWritableData", and "IReadWriteData". Please note: while "IReadableData" does not provide any means for mutating data, without any stretching the imagination implies the immutability of the data. If something is immutable, no one will be cheated on anyone; which clearly does not apply to an object of type MyData.

0
source

Source: https://habr.com/ru/post/1368999/


All Articles