Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Обязательный вызов функции базового класса в классе-наследнике

10K
04 апреля 2011 года
Cybernetic
106 / / 22.07.2009
Здравствуйте.
Подскажите, есть ли в C# средство, путем которого я могу обязать в перегруженных методах класса-наследника вызывать методы класса-родителя?

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

И еще: какие есть возможности для того, чтобы уйти от дублирования кода? Ведь по сути вызов проверки в каждой реализации алгоритма есть дублирование, что не есть хорошо. Жду советов профессионалов :)
2.1K
04 апреля 2011 года
Norgat
452 / / 12.08.2009
Цитата:
Моя ситуация: есть алгоритм как базовый класс, есть несколько его реализаций. Параметры одни и те же. При этом нужно делать предварительную проверку параметров, которую логично запихать в базовый класс. Как мне сделать, чтобы при написании новой реализации алгоритма я не забыл включить эту проверку, то есть обязать вызвать функцию проверки?

И еще: какие есть возможности для того, чтобы уйти от дублирования кода? Ведь по сути вызов проверки в каждой реализации алгоритма есть дублирование, что не есть хорошо.



На мнение профессионала не претендую, но что мешает использовать делегаты?

Пример:

Код:
class MyAlg
    {
        public delegate int DMyAlg(int param);

        DMyAlg _alg;

        public MyAlg(DMyAlg Alg)
        {
            _alg = Alg;
        }

        public int Run(int x)
        {
            if (x > 0) return _alg(x);
            else return _alg(x);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyAlg m1 = new MyAlg(x => x * x);
            MyAlg m2 = new MyAlg(x => x * x - x);

            Console.WriteLine(m1.Run(10));
            Console.WriteLine(m2.Run(10));

            Console.ReadLine();
        }
    }
242
04 апреля 2011 года
Оlga
2.2K / / 04.02.2006
Цитата:
Моя ситуация: есть алгоритм как базовый класс, есть несколько его реализаций. Параметры одни и те же. При этом нужно делать предварительную проверку параметров, которую логично запихать в базовый класс. Как мне сделать, чтобы при написании новой реализации алгоритма я не забыл включить эту проверку, то есть обязать вызвать функцию проверки


принудительно вызывайте функцию базового класса:

[code=c#]
class Base
{

public virtual void PrintMes()
{
Console.WriteLine("This is Base Message");
}
}

class Child : Base
{
public override void PrintMes()
{
base.PrintMes(); // вызов функции базового класса
Console.WriteLine("child Message");
}
}
[/code]

также, конструктор базового класса вызывается перед конструктором дочернего класса и в нем можно также оформлять какие то общие моменты, в том числе вызвать методы базового класса, при условии что они не перегружены в дочерних классах, т.к. в этом случае будет срабатывать метод дочернего класса (если создается дочерний объект);

5
05 апреля 2011 года
hardcase
4.5K / / 09.08.2005
А теперь правильное решение :)

Код:
public abstract class Base
{
    public void DoSomeWork(string a, int b)
    {
        // проверяем a
        // проверяем b
        DoSomeWorkInternal(a, b);
    }
   
    protected abstract void DoSomeWorkInternal(string a, int b);
}

public class Derived : Base
{
    protected override void DoSomeWorkInternal(string a, int b)
    {
        // работаем с корректными a и b
    }
}
242
05 апреля 2011 года
Оlga
2.2K / / 04.02.2006
hardcase
спасибо за правильный ответ, но есть но, у меня. можешь объяснить принципиальную разницу? как минимум я не врубаюсь почему в дочернем классе, в реализации метода DoSomeWorkInternal уже работаем с корректными 'а' и 'б'? разве не надо явно вызвать метод базового абстрактного класса DoSomeWork(string a, int b)
?
5
05 апреля 2011 года
hardcase
4.5K / / 09.08.2005
Подразумевается, что внешний клиент класса Base будет работать с методом DoSomeWork, ведь ему недоступен защищенный виртуальный метов DoSomeWorkInternal. Последний же будет реализован в каждом наследнике по-своему. Кроме того предполагается, что все внутренние вызовы происходят с заведомо корректными аргументами, проверка происходит (если нужна) лишь для аргументов публичных методов.
242
05 апреля 2011 года
Оlga
2.2K / / 04.02.2006
Цитата: hardcase
Подразумевается, что внешний клиент класса Base будет работать с методом DoSomeWork, ведь ему недоступен защищенный виртуальный метов DoSomeWorkInternal. Последний же будет реализован в каждом наследнике по-своему. Кроме того предполагается, что все внутренние вызовы происходят с заведомо корректными аргументами, проверка происходит (если нужна) лишь для аргументов публичных методов.



псп за ответ, только вот я не уверенна, что данный подход даст гарантию того, что метод DoSomeWork будет вызван вовремя, возможно это из за не понимания общей картины.

5
05 апреля 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: Оlga
псп за ответ, только вот я не уверенна, что данный подход даст гарантию того, что метод DoSomeWork будет вызван вовремя, возможно это из за не понимания общей картины.


Что значит вовремя? Клиенты иерархии классов Base только его (DoSomeWork) и могут вызывать - ко внутренней реализации у них нет доступа.

242
05 апреля 2011 года
Оlga
2.2K / / 04.02.2006
Цитата: hardcase
Что значит вовремя? Клиенты иерархии классов Base только его (DoSomeWork) и могут вызывать - ко внутренней реализации у них нет доступа.



ну если доступ только к этой функции, то убедил. а как внутренние запускаются? извини за тупые вопросы, я такого еще не видела (

5
05 апреля 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: Оlga
ну если доступ только к этой функции, то убедил. а как внутренние запускаются? извини за тупые вопросы, я такого еще не видела (


Как правило внутренние вызовы не требуют проверки аргументов.

242
05 апреля 2011 года
Оlga
2.2K / / 04.02.2006
Цитата: hardcase
Как правило внутренние вызовы не требуют проверки аргументов.



вопрос исчерпан. спасибо.

10K
06 апреля 2011 года
Cybernetic
106 / / 22.07.2009
Цитата: hardcase
А теперь правильное решение :)

Код:
public abstract class Base
{
    public void DoSomeWork(string a, int b)
    {
        // проверяем a
        // проверяем b
        DoSomeWorkInternal(a, b);
    }
   
    protected abstract void DoSomeWorkInternal(string a, int b);
}

public class Derived : Base
{
    protected override void DoSomeWorkInternal(string a, int b)
    {
        // работаем с корректными a и b
    }
}



Да, я предполагал такое решение, спасибо, теперь знаю, что оно правильное :)

А нельзя ли такого эффекта добиться путем проставления атрибутов? Вопрос может быть лишен смысла, потому что я еще не понял, как они используются. Ну кроме Serializable.
Как я это видел: функцию проверки в базовом классе помечаем неким атрибутом, который программисту будет говорить, где ее рекомендуется вызывать. Такое вообще возможно?

5
06 апреля 2011 года
hardcase
4.5K / / 09.08.2005
Цитата: Cybernetic

Как я это видел: функцию проверки в базовом классе помечаем неким атрибутом, который программисту будет говорить, где ее рекомендуется вызывать. Такое вообще возможно?


Атрибуты нужны не программистам, они нужны программам, обрабатывающим метаданные. Например в .NET 4 появились Code Contracts (реализация идеи контрактного программирования с помощью атрибутов), посмотрите на них.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог