简体   繁体   中英

Pattern for Exposing Interface Property as Interface

In the code below I'd like to expose property Bristles of Hedgehog as an IBristles in the IHedgehog interface, because a) that way I can just expose the getter and b) in external assemblies I don't have to reference all the assemblies that Bristles uses for more complicated methods like FindBristleDNA. This is what intuitively seems the right way to do it:

// straightforward interface for simple properties of Bristles -- 
// more complicated methods not exposed
public interface IBristles   {
    int Quantity{ get;  }
}
public class Bristles : IBristles {        

    public int Quantity{ get; set; }
    public MyObscureAssembly.ComplicatedObject FindBristleDNA(){ ... }
}

// simple interface for Hedgehog, which in turn exposes IBristles
public interface  IHedgehog {
    bool IsSquashed { get; }
    IBristles Bristles { get; }
}
// Here, Hedgehog does not properly implement IHedgehog, even though
// Bristles implement IBristles. Will not compile.
public class Hedgehog : IHedgehog {
    public bool IsSquashed { get; set; }
    public Bristles Bristles { get; set; }
}

My choices are either to expose Bristles directly on the IHedgehog interface (which I don't want to do), or to create another property with a different name (which I don't really want to do either, I'd like IHedgehog to have the property Bristles, in the same way the IBristles has the property IsSquashed.)

public interface  IHedgehog {
    bool IsSquashed { get; }
    IBristles ReadOnlyBristles { get; }
}
public class Bar : IBar    {
    public bool IsSquashed { get; set; }
    public Bristles Bristles { get; set; }
    public IBristles ReadOnlyBristles { get { return this.Bristles; }
}

which seems rather inelegant.

Of course, when dealing with an actual Hedgehog object we need the getter and setter fully functional, and the returned object to be a proper Bristles object. But, the IHedgehog just needs to return IBristles from the Bristles getter.

Is there a better/commonly used pattern?

Use explicit interface implementation:

public class Hedgehog : IHedgehog 
{
    public bool IsSquashed { get; set; }

    // your public property
    public Bristles Bristles { get; set; }

    // implements the interface
    IBristles IHedgehog.Bristles { get { return Bristles; } }
}
public class Hedgehog : IHedgehog 
{
    private Bristles _bristles;

    public bool IsSquashed { get; set; }

    public IBristles Bristles 
    { 
       get {return _bristles;}
       set {_bristles = value;}
    }
}

Should I think. To implement IHedgehog you need a getter that returns IBristles, not Bristles

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM