Pregunta

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?

¿Fue útil?

Solución

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.

Otros consejos

Do you really need to implement IValidatableObject explicitly in Base class ?

The solution would be - implement IValidatableObject implicitly in base class , mark it as virtual.

:-

Then implement IValidatableObject in derived class , implicitely, and mark it as virtual new. Dont forget to use interface name on derived class definition.

This is little different approach as compated to answer by @Konstantin Vasilcov. Using this approach you can have more derived classes of MyViewModel who can override the behavior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top