将setter添加到派生接口

时间:2011-07-19 14:40:11

标签: c# interface getter-setter

是否有可能以某种方式在C#中实现此行为:

public interface IReadOnly
{
    Data Value { get; }
}

internal interface IWritable : IReadOnly 
{
    Data Value { get; set; }
}

我希望能够将readonly接口公开给外部程序集,但在内部使用可写接口(我也可以用不同的方式实现)。

我知道我可以使用抽象类来实现IReadOnly但添加了setter,但这迫使我从该类派生所有内部实现。

4 个答案:

答案 0 :(得分:39)

这不是问题:

public interface IReadOnly {
    Data Value { get; }
}

internal interface IWritable : IReadOnly {
    new Data Value { get; set; }
}

internal class Impl : IWritable {
    public Data Value { get; set; }
}

Impl.Value属性实现负责两个 IReadOnly.Value和IWritable.Value,如此测试片段所示:

        var obj = new Data();
        var target = new Impl();
        var irw = (IWritable)target;
        irw.Value = obj;
        var iro = (IReadOnly)target;
        System.Diagnostics.Debug.Assert(Object.ReferenceEquals(iro.Value, obj));

答案 1 :(得分:0)

不可否认,这是一个警察,但我更喜欢做的是:

public interface IReadOnly
{
  Data Value { get; }
}

internal interface IWritable : IReadOnly 
{
  void SetValue(Data value);
}

虽然Hans Passant的回答有效,但我觉得很烦人,对于某些继承树,使用后代接口的代码仍然会抱怨它不知道哪个版本的"值"你指的是 - 即使是二传手!

答案 2 :(得分:-1)

Hans Passant给出了一个非常好的答案,我得到了类似的答案,但我想我可以做得更好:

public interface IReadOnly : IWritable
{
    new int MyValue { get; }
}

public interface IWritable
{
    int MyValue { get; set; }
}

public class Implementation : IReadOnly
{
    public int MyValue { get; private set; }

    int IWritable.MyValue
    {
        set { MyValue = value; }
        get { return MyValue; }
    }

    public static Implementation GetMyImplementation()
    {
        return ImplementationGateway<Implementation>.GetMyImplementation();
    }
}


public class ImplementationGateway<TImplementation>
    where TImplementation : class, IWritable, new()
{
    public static TImplementation GetMyImplementation()
    {
        return new TImplementation
            {
                MyValue = 1
            };
    }
}

public class Program
{
    public Program()
    {
        Implementation myImplementation = Implementation.GetMyImplementation();
        myImplementation.MyValue = 0; //This will and is supposed to fail
    }

}

我和先生的区别。 Passant的解决方案是,我的IReadOnly继承自我的IWritable。作为此代码的结果,您无法在Program类中设置MyValue,这可能是您希望它工作的方式。检索并映射Gateway类中的数据,然后将其作为除此之外的只读值。有了这个,你就有了读/写分离。 作为一个额外的好处,你的DAL唯一知道你的对象,是他们共享的界面作为“合同”的方式。
nterface D efined M odel。

答案 3 :(得分:-2)

为了使其正常工作,应该声明并实现一个IReadWrite,它继承IReadable和IWritable,并包含一个“新的”读写属性。否则,具有单独的get和set属性但没有get-set属性的接口既不可读也不可写。