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是仅可写的属性。。。