CJC
CJC

Reputation: 817

Explicitly set an internal property from an inherited interface C#

I have a scenario. I am trying to wrap my code up so that I have generic entities which instantiate themselves according to the realm that they are in.

Like an onion which only has a layer which it deals with itself but at the same time allowing somebody from a higher level to trigger the internal layers to start doing something. It allows me to package my components in a nicer and more reusable manner since i will be able to implement code which propagates safely to all required modules without affecting higher levels which may be deriving from the same base classes. So basically there will be a hierarchy of levels which classes will share commonality.

In short, I have a property of type interface(IBar) inside an interface(IFoo) which is inheriting another interface(IFooBase), and i have another property inside this base interface which is the same name of the property from interface above of a type which is a base interface of its original(IBarBase)

My problem is my implementation of Foo, which calls a method from FooBase which accesses property of IBar cannot access IBarBase because the object is not instantiated, the reason being that inherited interfaces of the same time performs hiding of properties instead of overwriting.

Any advice will be greatly appreciated on how i can go about assigning IBarBase with an instantiated object of Bar (of which is actually an implementation of IBar and derived from IBarBase) so that i may be able to access the property from a lower level to perform some task.

Sorry is this sounding too complex? im not sure if i am making any sense, the code before is for reference. And a picture also for illustration

enter image description here

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

Upvotes: 2

Views: 1436

Answers (2)

stuartd
stuartd

Reputation: 73243

You should use an explicit implementation of the interface rather than overriding the instproperty:

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

   IBar IFoo.inst { get; set; }
}

Then this test passes:

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

Upvotes: 1

Patrick Hofman
Patrick Hofman

Reputation: 156948

You have another variable inst which you have created in Foo (note the new keyword):

public new IBar inst { get; set; }

It hides the other inst you have in your base class. So you are not setting FooBase.inst in Foo, you are setting Foo.inst. Hence, FooBase.inst is null.

You could explictly implement the interface member:

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

Upvotes: 4

Related Questions