Переопределение / сокрытие реализованного метода интерфейса Explicity

2

У меня возникли проблемы с переопределением метода, который явно реализует интерфейс.

У меня есть два класса. Базовый, называемый OurViewModel, и унаследованный, называемый MyViewModel. Они совместно используют метод под названием Validate, и до недавнего времени мне удалось скрыть базовую версию метода, например:

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


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

Все это изменилось пару дней назад. На сцене появился новый интерфейс -

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

Впоследствии, OurViewModel также был изменен. Я не просил этого, но это случилось, и я должен жить с ним. Класс теперь выглядит следующим образом:

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

Мне сложно определить, как переопределить или скрыть этот перезаписанный метод Validate в MyViewModel. Если я попытаюсь поместить ключевое слово new подписи метода (как и раньше), я получаю ошибку компиляции. Я также не могу объявить метод Validate как виртуальный в OurViewModel, так как он явно реализует интерфейс.

Что делать? Если я просто повторно реализую Validate в MyViewModel, используя подпись из документа IValidatableObject, это скроет реализацию в OurViewModel, или я прошу о каких-либо проблемах из-за правил наследования?

  • 0
    снова вы допустили ошибку в вопросе ... если базовый член не является виртуальным, вы не можете сделать его новым в производном классе.
  • 0
    @Dhananjay ты не прав ...
Показать ещё 2 комментария
Теги:
inheritance
interface

2 ответа

4
Лучший ответ

Я думаю, что вам нужно реализовать этот интерфейс неявно и в производном классе.

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

И затем

OurViewModel v = new OurViewModel();
MyViewModel m = new MyViewModel();

IValidatableObject ivo = v;
ivo.Validate(null);

ivo = m;
ivo.Validate(null);

Кроме того, если интерфейс реализован явно, вы можете получить доступ только к реализации через ссылку на интерфейс. Помните, если вы попытаетесь сделать

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

Он будет вызывать исходный метод Validate класса, а не реализацию интерфейса. Я думаю, что старые методы следует удалить, чтобы избежать возможных ошибок.

0

Вам действительно нужно явно реализовать IValidatableObject в базовом классе?

Решение будет: реализовать IValidatableObject неявно в базовый класс, отметьте его как виртуальный.

: -

Затем реализуем IValidatableObject в производном классе, неявно и отметьте его как виртуальное новое. Не забывайте использовать имя интерфейса на производном определение класса.

Это немного другой подход, который скомпонован для ответа Константина Васильцова. Используя этот подход, вы можете иметь более производные классы MyViewModel, которые могут переопределить поведение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню