C# 来自不同接口的Getter和setter

C# 来自不同接口的Getter和setter,c#,interface,C#,Interface,我真的需要这样的东西: interface IReadableVar { object Value { get; } } interface IWritableVar { object Value { set; } } interface IReadableWritableVar : IReadableVar, IWritableVar { } interface IReadableWritableVar : IReadableVar, IWritableVar {

我真的需要这样的东西:

interface IReadableVar
{
    object Value { get; }
}

interface IWritableVar
{
    object Value { set; }
}

interface IReadableWritableVar : IReadableVar, IWritableVar
{
}
interface IReadableWritableVar : IReadableVar, IWritableVar
{
    new object Value { get; set; }
}
然而,当我尝试使用
IReadableWritableVar.Value
时,我会得到编译错误,除非我显式地强制转换到基接口,如下所示:

static void Main()
{
    IReadableWritableVar var = null;
    var t = var.Value;  // <-- CS0229: Ambiguity between 'IReadableVar.Value' and 'IWritableVar.Value'
    var.Value = null;   // <-- CS0229: Ambiguity between 'IReadableVar.Value' and 'IWritableVar.Value'

    var v = ((IReadableVar)var).Value;  // compiles fine
    ((IWritableVar)var).Value = null;   // compiles fine
}
static void Main()
{
IReadableWritableVar=null;

var t=var.Value;//一个可能的解决方法是修改界面
IReadableWritableVar
如下:

interface IReadableVar
{
    object Value { get; }
}

interface IWritableVar
{
    object Value { set; }
}

interface IReadableWritableVar : IReadableVar, IWritableVar
{
}
interface IReadableWritableVar : IReadableVar, IWritableVar
{
    new object Value { get; set; }
}
但请记住,有效的实施应该是:

class ReadableWritableVar : IReadableWritableVar
{
    public object Value
    {
        get { throw new NotImplementedException(); }
        set { throw new NotImplementedException(); }
    }

    object IWritableVar.Value
    {
        set { throw new NotImplementedException(); }
    }

    object IReadableVar.Value
    {
        get { throw new NotImplementedException(); }
    }
}
一个更具体的例子:

class ReadableWritableVar : IReadableWritableVar
{
    public object Value
    {
        get { return ((IReadableVar)this).Value; }
        set { ((IWritableVar)this).Value = value; }
    }

    object _val;

    object IWritableVar.Value { set { _val = value; } }

    object IReadableVar.Value => _val;
}
或者更好:

class ReadableWritableVar : IReadableWritableVar
{
    public object Value { get; set; }

    object IWritableVar.Value { set { Value = value; } }

    object IReadableVar.Value => Value;
}

使用接口的抽象类istead将解决您的问题

public abstract class ReadableWritableVar : IReadableVar, IWritableVar
{
    public object Value { get; set; }       
}

实际上,Getter和Setter只是两个方法。当我们使用
IReadableWritableVar
接口时,有两个从基本接口继承的名称相同的方法,编译器不知道应该使用这两个方法中的哪一个,因此存在歧义

当我们将其转换到其中一个接口时,另一个成员就消失了,并且没有错误

如果我们实现这些成员,则不会出现错误,因为编译器将使用该实现:

class ReadableWritableVar : IReadableWritableVar
{
    public object Value { get; set; }
}

var @var = new ReadableWritableVar();
var t = @var.Value;

如果需要使用接口而不是类,您还可以使用@Alessandro D'Andria答案中的显式接口成员实现。

有趣的问题。我认为扩展方法在这种情况下会有所帮助

public static class Extension
{
    public static object GetValue(this IReadableVar v)
    {
        return v.Value;
    }

    public static void SetValue(this IWritableVar v, object value)
    {
        v.Value = value;
    }
}
您需要更改代码才能使用它:

IReadableWritableVar variable = null;
var t = variable.GetValue();
variable.SetValue(null);

扩展方法为您执行强制转换。

一种可能的替代方法是使用显式(java样式)get和set方法,而不是属性:

interface IReadableVar
{
    object GetValue();
}

interface IWritableVar
{
    void SetValue(object value);
}

interface IReadableWritableVar : IReadableVar, IWritableVar
{

}
然后,用法变为:

static void Main(string[] args)
{
    IReadableWritableVar aVar = null;

    var t = aVar.GetValue();
    aVar.SetValue(null);
}

我认为编译器的设计并不是基于getter或setter区分不同接口中的相同属性。请注意,
IWritableVar
是可疑的,因为只写属性是可疑的。任何可以写属性的调用程序都应该能够读到它,而这不应该发生“没有意义,你可能想要一个方法,而不是一个属性。@Jeroenmoster这些变量实际上更复杂,并且连接到一个硬件系统,并且其中一些东西只能被写入。同时它们必须是WPF绑定系统使用的属性。在不了解整个系统的情况下,解释起来很复杂,但这确实会使这样做。将WPF中的属性添加到问题文本中可能会很有成效。但不要称它为
IReadableWritableVar
,如果它不是一个接口,可以称它为
ReadableWritableVar
AbstractReadableWritableVar
。不幸的是,这必须是一个接口,而实现它的类不起作用只需注意:您不需要显式实现。
class ReadableWritableVar:IReadableWritableVar{public object Value{get;set;}
编译很好。只需将
新值
属性添加到“IReadableWritableVar”中,就解决了我的问题。实现它的类正在进行非显式实现。这是一个解决方法,但效果很好-非常感谢。这是一个有趣的方法,但在这种情况下,我只需使用
SetValue
GetValue
m方法并完全删除属性。不幸的是,属性是必需的,因为它必须与WPF绑定系统一起工作。这些只是内部方法,但我认为是两种不同的方法。这就是为什么我不理解编译器为什么会这样做。如果我使用两种方法(setter和getter)问题不存在属性。不幸的是,这必须是一个属性,因为WPF绑定系统将使用它。你说这直接从WPF中的绑定到硬件?这里需要更多的层。@BryanBoettcher嗯,实际上我有更多的层。但仍然有些东西只能在硬件上编写在这些层中,re level是仅可写的属性。。。