Monday, February 21, 2011

Interface doesn't accept inherited member (OO question)

I feel like a fool, but here goes:

public interface IHasErrorController{
  ErrorController ErrorController { get; set; }
}

public class DSErrorController: ErrorController{yadi yadi ya}

public class DSWebsiteController : Controller, IHasErrorController{
    public DSErrorController ErrorController { get; set; }
}

This gives me an error saying DSWebsiteController.ErrorController cannot implement IHasErrorController despite DSErrorController being inheritted from ErrorController.

Also, suggestions for a better naming so that the type ErrorController and the field Errorcontroller don't look the same are welcome (naming is hard).

From stackoverflow
  • C# (at the moment) has very little [co|contra]variance support; as such, the interface implementation must be an exact match, including the return type. To keep your concreate type on the class API, I would implement the interface explicitly - i.e. add:

    ErrorController IHasErrorControlloer.ErrorController {
      get {return this.ErrorController;}
      set {this.ErrorController = (DSErrorController)value;}
    }
    

    Alternatively, simply change the type of the property to ErrorController - this may (or may not) give what you need.

    borisCallens : With your code sollution you mean to put a cast in your setter, right? Just making sure I understand it all right.
    Marc Gravell : My bad; have added.
  • This is true; that is not allowed. (The proper name is "Covariant return types")

    Note that DSWebsiteController.ErrorController can physically return a DSErrorController object; it's just that the property's return value must be defined as ErrorController.

  • Ok, so it's not me not knowing my OO principles then. Is this something that is planned to be included?

    I find it strange that I never came across this since this is a rather usefull functionality in my eyes. Or are there better ways to solve the problem at hand?

    Thanks Marc, now I finally understand what this "implement interface explicitly" is all about :)

    Marc Gravell : It is certainly something that the C# team talks about occasionally, but who knows what we'll get when. It isn't a simple area, but arguably the compiler (with a different spec!) could have done some inference for us in the above example (i.e. it could have done what I did).
    Marc Gravell : Scratch my comment about inference; the cast I forgot means that this wouldn't be a safe example - but I have /seen/ perfectly safe examples that would qualify.

0 comments:

Post a Comment