tags:

views:

243

answers:

3

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).

+4  A: 

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.

Marc Gravell
With your code sollution you mean to put a cast in your setter, right?Just making sure I understand it all right.
borisCallens
My bad; have added.
Marc Gravell
A: 

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.

James Curran
A: 

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 :)

borisCallens
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.
Marc Gravell