【问题标题】:Explicitly set an internal property from an inherited interface C#从继承的接口 C# 显式设置内部属性
【发布时间】:2016-03-17 12:00:47
【问题描述】:

我有一个场景。我正在尝试包装我的代码,以便我拥有根据它们所在的领域实例化自己的通用实体。

就像一个洋葱,它只有一层它自己处理,但同时允许更高级别的人触发内部层开始做某事。它允许我以更好和更可重用的方式打包我的组件,因为我将能够实现安全地传播到所有必需模块的代码,而不会影响可能源自相同基类的更高级别。所以基本上会有一个层次结构,类将共享共性。

简而言之,我在一个接口 (IFoo) 内有一个接口 (IBar) 类型的属性,它继承了另一个接口 (IFooBase),并且我在这个基接口内有另一个属性,它与接口中的属性名称相同以上是其原始(IBarBase)的基本接口的类型

我的问题是我的 Foo 实现,它从 FooBase 调用访问 IBar 属性的方法无法访问 IBarBase,因为该对象未实例化,原因是同时继承的接口执行隐藏属性而不是覆盖。

任何关于如何为 IBarBase 分配 Bar 的实例化对象(实际上是 IBar 的实现并从 IBarBase 派生)的任何建议都将不胜感激,这样我就可以从较低的位置访问该属性执行某些任务的级别。

抱歉,这听起来太复杂了吗?我不确定我是否有任何意义,之前的代码仅供参考。还有一张图片作为说明

public interface IFoo : IFooBase
{
    new IBar inst { get; set; }
}

public interface IFooBase
{
    IBarBase inst { get; set; }
    void SetEventHandlers();
}

public interface IBar : IBarBase
{
    int stuff { get; set; }
}

public interface IBarBase
{
    int otherStuff { get; set;}
}

public class Foo : FooBase, IFoo
{
    public Foo()
    {
        inst = new Bar();
        SetEventHandler();
    }

    public new IBar inst { get; set; }
}

public class FooBase : IFooBase
{
    public void SetEventHandler()
    {
        inst.otherStuff = 123;
    }

    public IBarBase inst { get; set; }
}

public class Bar : BarBase, IBar
{
    public int stuff { get; set; }
}

public class BarBase : 
{
    public int otherStuff { get; set;}
}

【问题讨论】:

  • 您能否指出您代码中出错的那一行?我很难理解你的设计和问题。
  • 当 Foo 在构造函数中调用 SetEventHandler() 时。即使我已经实例化了 inst,但当我尝试分配 inst.otherstuff = 123 时,inst 仍显示为 null。

标签: c# inheritance interface


【解决方案1】:

您在Foo 中创建了另一个变量inst(注意new 关键字):

public new IBar inst { get; set; }

它隐藏了您在基类中拥有的另一个inst。所以你不是在Foo 中设置FooBase.inst,而是在设置Foo.inst。因此,FooBase.inst 为空。

你可以显式实现接口成员:

public class Foo : FooBase, IFoo
{
    IBar IFoo.inst { get { return instAsIBar; } set { instAsIBar = value; } }

    public IBar instAsIBar { get { return (IBar)this.inst; } set { this.inst = value; } }
}

【讨论】:

  • 肯定同意,但我的问题是如何将 Foo.inst 和 FooBase.inst 设置在一起。因为我知道 Foo,inst 实际上是派生自 FooBase,inst 的类型所以实际上我希望它们都链接在一起。
  • 我觉得差不多是正确的,但是set直接设置为内部IBarBase的类型。现在我无法访问 IBar 中定义的任何属性。如何同时设置两者的属性?
  • 你的意思是像我更新的代码中的instAsIBar?设置一个属性也会设置另一个属性,因为它只是封装了另一个。
  • 是的,我认为这是可行的,但我必须将所有引用更改为来自 instAsIBar 才能访问 IBar 的属性。是否可以使用相同的名称,即 inst?
  • 并非如此。对不起。
【解决方案2】:

您应该使用an explicit implementation of the interface 而不是覆盖instproperty:

public class Foo : FooBase, IFoo
{
   public Foo() 
   {
        inst = new Bar();
        SetEventHandlers();
   }

   IBar IFoo.inst { get; set; }
}

那么这个测试通过了:

[TestFixture]
public class TC 
{
    [Test]
    public void t() 
    {
        Foo f = new Foo();
        ((FooBase)f).inst.otherStuff.Should().Be(123);
    }
}

【讨论】:

  • 必须把它交给帕特里克,因为他的答案更完整。还是谢谢
猜你喜欢
  • 1970-01-01
  • 2017-05-12
  • 2011-02-17
  • 2010-12-23
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
相关资源
最近更新 更多