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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: C# - обнаружил интересную "фишку"  (Прочитано 11723 раз)
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 » new

...
Получим ошибку, так как не можем оуверрайдить 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 » 

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

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

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines