【问题标题】:Why does interface A hide property from interface B为什么接口A隐藏接口B的属性
【发布时间】:2017-06-30 09:59:28
【问题描述】:

请参阅下面的代码。 Visual Studio 2017 告诉我 IGetSet.Value 隐藏了 IGet.Value 属性,如果有意,我应该添加 new 关键字。我理解关于类隐藏属性的概念,但是当涉及到接口时,我看不到消息的重点。我是否添加 new 关键字当然在行为上没有区别。

我想要这 2 个接口的堆叠,因为我想要实现读写接口的对象在只允许获取值的方法中使用。

现在我的问题是:

  1. 这是实现我想要的方式吗?我将“隐藏”属性的消息视为一个信号,即“您正在这里做一些您可能不想做的事情,请尝试以不同的方式解决它”。
  2. 一个接口如何隐藏另一个接口的属性?它不依赖于接口的实现吗?那么为什么是消息呢?

    public interface IGetSet : IGet
    {
        new string Value { get; set; }
    }
    
    public interface IGet
    {
        string Value { get; }
    }
    
    public class Tester : IGetSet
    {
        public string Value { get; set; }
    }
    
    [Test]
    public void InterfaceTest()
    {
        IGetSet tester = new Tester();
        tester.Value = "My Value";
        IGet getteronly = tester;
        var value = getteronly.Value;
    }
    

如果我尝试使用下面的代码解决它,我会收到此编译错误“CS0229 Ambiguity between 'IGet.Value' and 'ISet.Value'”

public interface ISet
{
    string Value { set; }
}

public interface IGet
{
    string Value { get; }
}

public interface IGetSet : IGet, ISet
{

}

【问题讨论】:

  • @Evk3 这只发生在隐式实现接口并且在代码中使用该属性时。使用行导致编译错误。感谢您指出了这一点。当代码中没有使用该属性时,虽然实现了接口,但代码确实可以编译。感谢您指出这一点!

标签: c# interface get set


【解决方案1】:

这是实现我想要的方式吗?

是的。

我将“隐藏”属性的消息视为一个信号,即“您在这里做的事情可能不想做,请尝试以不同的方式解决它”。

不,这意味着您必须评估这是否是故意的。 您是否真的打算创建第二个属性定义来推翻第一个定义? 是的,在这种情况下您会这样做,但有时您不会。所以这就是为什么会有一个警告要求你明确告诉你想要什么。

附带说明一下,当您使用显式接口实现时,您实际上可能会得到两个属性的不同实现:

public class Tester : IGetSet
{
    string IGet.Value { get { return "A"; } }

    string IGetSet.Value { get { return "B"; } set { } }
}

看到警告有什么问题吗?

【讨论】:

  • 支持显式接口。如果通过接口 IGetSet 寻址对象,则 IGet.Value 不可见。所以我会说那里没有藏身之处。如果您有一个 Tester 实例,由于显式实现,您将看不到任何 Value 属性。所以我仍然不同意关于属性被隐藏的消息。
  • 有隐藏:你没看到get 属性吧?您正在替换界面中Value 的定义。
  • 是的,我现在明白了!多么温暖的感觉,那光,我拥抱了主的光!只是在这里玩得开心。谢谢!
【解决方案2】:

如果两个接口具有相同的属性,则必须显式实现它们

public interface ISet
{
    string Value { set; }
}

public interface IGet
{
    string Value { get; }
}

public class GetSetClass : IGet, ISet
{
    public string Value { get; set; }
    string IGet.Value // Explicitly implementation
    {
        get { return Value; }
    }

    string ISet.Value // Explicitly implementation
    {
        set { Value = value; }
    }
}

【讨论】:

  • 不,如果您想实际覆盖接口定义中的属性,则不需要。这就是第一个代码示例所做的。第二个是不必要的,在我看来,它会带来比它更能解决的问题。
  • @PablonotPicasso 这不是我想要的,因为我认为它需要不必要的代码来实现只读限制。
猜你喜欢
  • 2014-07-05
  • 2014-11-02
  • 1970-01-01
  • 1970-01-01
  • 2011-10-06
  • 2019-07-26
  • 2019-10-14
  • 2020-01-07
  • 1970-01-01
相关资源
最近更新 更多