2013-12-17 4 views
2

У меня есть базовый класс, где мне нужно убедиться, что все виртуальные методы перезаписаны в специализациях классов. Я не могу использовать абстрактный класс/методы, так как мне нужно выполнить некоторый код в базовых методах.Убедитесь, что все виртуальные методы переопределены

Как это сделать?

public class BaseClass 
{ 
    public virtual void DoStuff() 
    { 
    // do something 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public override void DoStuff() 
    { 
    // do derived work 
    base.DoStuff(); 
    } 
} 
+0

Даже если вы могли бы (я не верю, что можно), вы Wouldn «Невозможно заставить исполнителей« вызывать »ваши базовые методы, когда они их переопределяют, - это тоже требовалось? –

+0

@Damien_The_Unbeliever хорошо, у меня есть куча тестового кода, который мне нужно протестировать на некоторых репозиториях. Поэтому мне нужно убедиться, что если я добавлю тесты в «базовый тестовый класс», тогда все тесты репозиториев будут проверять новые тесты, которые я добавил. В основном я пытаюсь преодолеть ограничение атрибута TestCaseAttribute nunit, который поддерживает только примитивные типы. Для этого существует ряд довольно простых решений, но все они уничтожают обзор тестов nunit и затрудняют мне выяснение, какие тесты терпят неудачу на каких классах. –

ответ

11

Используйте крючки, более известный как template method pattern:

public abstract class BaseClass 
{ 
    public void Start() 
    { 
    // do something 
    OnStart(); 
    // do something else 
    } 
    protected abstract void OnStart(); 
} 

Это работает мой самый любимый Hollywood principle, основой многих структур: не звоните нам, мы будем называть вас!

+0

, но это означало бы просто перемещение требования для выполнения метода Start() вместо этого, правильно? –

+0

Ой, подождите, что ваша конструкция делает базовый класс вызовом производного класса. Требование - это наоборот. Я хочу, чтобы производный класс вызывал базовый класс. –

+0

@JesperLundStocholm Да, это гарантирует, что производная реализация вызывается, потому что абстрактный класс называет ее самой. Вы не можете заставить все производные классы вызывать базовый класс - боюсь, вы не сможете применить это правило. Документация и командная дисциплина - ваш лучший выбор. – dcastro

2

Если вы реализуете абстрактный класс, как это, он будет делать то, что вам нужно.

public abstract class BaseClass 
{ 

    protected abstract void doAbstractStuff(); 

    public void DoStuff() 
    { 
    //base class code lives here 
    doAbstractStuff(); 
    //or here? 
    } 
} 
+0

Мне нужно поместить некоторый код в метод базового класса doAbstractStuff() –

+2

Вы поместили этот код в метод DoStuff. – Liam

0

Я не уверен, что есть простой способ сделать это, но вы могли бы сделать это вместо:

public class BaseClass 
{ 
    public abstract void DoStuff(); 

    protected void DoStuffInternal() 
    { 
    // do something 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public override void DoStuff() 
    { 
    // do derived work 
    DoStuffInternal(); 
    } 
} 
+0

Это означает, что вы должны помнить, чтобы вызвать внутренний метод на каждом DerivedClass? – Liam

+0

@Paddy Я думаю, что это добавляет искусственный шаг к использованию базового класса, который делает производное использование довольно неинтуитивным. –

+0

Должен был добавить комментарий. ответ dcastro намного лучше, чем это - он получил мой голос :) – Paddy

Смежные вопросы