Search code examples
c#inheritanceinterfaceexplicit-implementation

Overriding / hiding an explicity implemented interface method


I'm having trouble overriding a method that explicitly implements an interface.

I have two classes. A base one called OurViewModel, and an inherited one called MyViewModel. They share a method called Validate, and until recently I was able to hide the base version of the method, like so:

public class OurViewModel
{
  public bool Validate(ModelStateDictionary modelState){ return true; }
}


public class MyViewModel : OurViewModel
{
  public new bool Validate(ModelStateDictionary modelState) {return false;}
}

This all changed a couple of days ago. A new interface has appeared on the scene--

public interface IValidatableObject
{
  IEnumerable<ValidationResult> Validate(ValidationContext validationContext);
}

Subsequently, OurViewModel has also been changed. I did not request this, but it happened and I have to live with it. The class now looks like this:

public class OurViewModel : IValidatableObject
{
  IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext) {..}
}

I'm having difficult time figuring out how to override or hide this rewritten Validate method in MyViewModel. If I try placing the new keyword the method signature (as I did originally) I get a compilation error. I also can't declare the Validate method as virtual in OurViewModel, as it's explicitly implementing an interface.

What to do? If I simply re-implement Validate in MyViewModel using the signature from IValidatableObject, will that hide the implementation in OurViewModel, or am I asking for trouble in some way because of inheritance rules?


Solution

  • I think you need to implement this interface implicitly in the derived class as well.

    public class MyViewModel : OurViewModel, IValidatableObject
    {
        IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
        {
            //...
        }
    }
    

    And then

    OurViewModel v = new OurViewModel();
    MyViewModel m = new MyViewModel();
    
    IValidatableObject ivo = v;
    ivo.Validate(null);
    
    ivo = m;
    ivo.Validate(null);
    

    Besides if an interface is implemented explicitly, you can only access the implementation through a reference to the interface. Remember, if you try to do

    OurViewModel v = new OurViewModel();
    v.Validate(null);
    

    It will call the original Validate method of the class, not the interface implementation. I think the old methods should be removed to avoid possible mistakes.