Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a class from 2 interfaces that share some parts

Tags:

c#

oop

interface

Is the following not a good practice?

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

The reason I ask is that resharper gives me the following warning: "possible ambiguity while accessing by this interface"

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

like image 345
Raj Rao Avatar asked Aug 25 '11 17:08

Raj Rao


2 Answers

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

However, usually a wrapper class is used to provide readonly access to something, that way it can't be cast to anything that does provide 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.
like image 191
Joel B Fant Avatar answered Oct 19 '22 12:10

Joel B Fant


You need to make one or both of the implementations explicit:

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

When you mark one as explicit, it can only be accessed when specifically cast as that type:

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

If you choose to not mark one as explicit, it will be the property chosen when cast as other appropriate types.

like image 40
Tejs Avatar answered Oct 19 '22 11:10

Tejs