Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: C# - обнаружил интересную "фишку"  (Прочитано 11660 раз)
0 Пользователей и 1 Гость смотрят эту тему.
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« : 30-06-2006 06:11 » 

Знаю что классы бывают sealed. Понятно для чего. Но также sealed могут быть методы, и тут я наткнулся на такую штуку, что есть способ обхода sealed методов Улыбаюсь

Создадим класс с виртуальным методом :
Код:
public class Demo
{
public virtual int Sum(int a, int b)
{
return a + b;
}
}
Создадим класс наследник предыдущего и оуверрайдим метод Sum, а также сделаем его sealed, для того чтобы в классе наследнике больше нельзя было оуверрайдить этот метод.
Код:
public class Demotester : Demo
{
public sealed override int Sum(int a, int b)
{
return base.Sum (a, b);
}
}
Опять же создадим класс наследник предыдущего и попробуем оуверрайдить в нём метод Sum
Код:

public class Tester : Demotester
{
public override int Sum(int a, int b)
{
return base.Sum(a, b);
}
}
Получим ошибку, так как не можем оуверрайдить sealed метод. Но! есть оказывается способ это обойти Улыбаюсь
Код:

public class Tester : Demotester
{
public new int Sum(int a, int b)
{
return base.Sum(a, b);
}
}
Всё скомпилиться и отработает Улыбаюсь Какой то shadowing получается Улыбаюсь
Теперь вопрос к знатокам : Это что ? Фишка языка ? Объясните мне пожалуйста зачем это нужно то ?
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Alf
Гость
« Ответ #1 : 30-06-2006 06:42 » 

...
Получим ошибку, так как не можем оуверрайдить sealed метод. Но! есть оказывается способ это обойти Улыбаюсь

Это вовсе не обход. Посредством new ты заявил, что не намерен переопределять унаследованный метод, а создаешь свой собственный с таким же именем, который прячет одноименный метод предка. То есть в этом месте у тебя перестает работать виртуальный механизм (vtbl и прочее) и появляется обычный метод.

Грубая аналогия - если у тебя есть член класса X и ты в меоде объявил локальную переменную с таким же именем, ты просто "спрятал" имя из охватывающей метод области видимости, а вовсе не переопределил переменную. С первоначальной переменной новая не имеет ничего общего, кроме имени.

Кстати, погляди внимательнее на диагностику компилятора. Если у тебя есть базовый класс B:

Код:
public class B
{
  virtual void M() { }
}

и производный от него C:

Код:
public class C:
{
  void M() { }
}

, то при компиляции ты получишь предупреждение о неоднозначности ситуации. Выдается сообщение что-то вроде "уточни свои намерения, задай override, если хочешь переопределить виртуальный метод, или new, чтобы перекрыть унаследованный.
Записан
Alf
Гость
« Ответ #2 : 30-06-2006 06:48 » 

(Продолжение)

Я предполагаю (следует проверить на практике), что ситуация такова.

Допустим, имеем:

Код:
C c = new C();
B b = c;
...
c.M(); // вызывается C.M()
b.M(); // вызывается B.M()

Так что на переопределение метода базового класса это, увы, ничуть не похоже. Обращение к объекту через указатель на базовый класс проигнорирует новый метод и по-прежнему использует базовый.
Записан
Alf
Гость
« Ответ #3 : 30-06-2006 06:51 » 

И в завершение темы цитата:

Цитата
new Modifier
Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.
Consider the following class:
public class MyBaseC
{
   public int x;
   public void Invoke() {}
}
Declaring a member with the name Invoke in a derived class will hide the method Invoke in the base class, that is:
public class MyDerivedC : MyBaseC
{
   new public void Invoke() {}
}

(сами знаете откуда (С) ).
Записан
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #4 : 30-06-2006 07:27 » 

Спасибо за столь подробное объяснение. Но я всё ещё немного туплю.
В методе который я привёл
Код:
public class Tester : Demotester
{
     public new int Sum(int a, int b)
     {
          return base.Sum(a, b);
     }
}
пускай и создастся отдельный метод через new, но в результате base.Sum(a, b); вызовет sealed метод из класса родителя , Или я ошибаюсь ?
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #5 : 30-06-2006 07:32 » new

Alf, сорри, тупанул я немного Улыбаюсь Вопрос последний снимается Улыбаюсь
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines