向派生接口添加setter

本文关键字:setter 添加 接口 派生 | 更新日期: 2023-09-27 18:02:26

是否有可能在c#中实现这种行为:

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

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

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

向派生接口添加setter

这不是问题:

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。值属性实现处理 IReadOnly。值和IWritable。值,如以下测试片段所示:

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

无可否认这是一种逃避,但我更喜欢这样做:

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

虽然Hans Passant的回答是有效的,但我发现对于某些继承树,使用后代接口的代码仍然会抱怨它不知道你引用的是哪个版本的"值"——即使使用setter!

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

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 基础上。