class Control
{
protected:
virtual void SomeMethod()
{
//Делает то, что нужно
}
};
class SomeStandatdControl : public Control
{
protected:
virtual void SomeMethod()
{
//Делает не то, что нужно
}
};
class MyControl : public SomeStandatdControl
{
protected:
virtual void SomeMethod()
{
//Вот тут вызов нужного метода через явную квалификацию
Control::SomeMethod();
}
};
А теперь вопрос, как такое написать на шарпе?
public class Control
{
protected virtual void SomeMethod()
{
//Делает то, что нужно
}
}
public class SomeStandatdControl : Control
{
protected override void SomeMethod()
{
//Делает не то, что нужно
}
}
public class MyControl : SomeStandatdControl
{
protected override void SomeMethod()
{
//Как тут вызвать Control.SomeMethod???
Control.SomeMethod(); // Error: Cannot access protected member
(this as Control).SomeMethod(); // Error: Cannot access protected member
}
}
public class Control
{
protected virtual void SomeMethod()
{
SomeMethodOfControl();
}
protected void SomeMethodOfControl()
{
//Делает то, что нужно
}
}
public class SomeStandatdControl : Control
{
protected override void SomeMethod()
{
//Делает не то, что нужно
}
}
public class MyControl : SomeStandatdControl
{
protected override void SomeMethod()
{
//Как тут вызвать Control.SomeMethod???
//Control.SomeMethod(); // Error: Cannot access protected member
//(this as Control).SomeMethod(); // Error: Cannot access protected member
SomeMethodOfControl();
}
}
иначе никак.
для вызова предыдущего в цепочке: base.SomeMethod();
Надо пока не поздно написать в МС, может, в следующей версии добавят. :crush: Хотя ты первый, кому это понадобилось.
Тут проблема в том, что обычно такие вещи в диезе разруливаются путем приведения экземпляра нужному типу. Т.е. если есть экз. типа С (потомка В, который в свою очередь потомок А), то нужный метод вызывается путем приведения к типу А. Однако в данном случае это не помогает
Это вопрос-то скорее философский. Если разработчик базового класса сделал свою реализацию — зачем вам лезть дальше в дебри дерева наследования, чтобы вытащить что-то оттуда из самого нутре? Мало ли зачем он его перегрузил — может он там состояние объекта своего меняет? А вы хотите в обход его реализации пойти.
А если Вы сами разрабочик обоих классов — легко сделаете то что например я предлагал, если уж не хочется повторять реализацию.
D_S>Здравствуйте, Воронков Василий, Вы писали:
ВВ>>Уроды, в общем.
D_S>Согласен. Кто мешал сделать что-либо наподобие: D_S>
Здравствуйте, Алексей Одинцов, Вы писали:
АО>Здравствуйте, Dr_Sh0ck, Вы писали:
АО>Это вопрос-то скорее философский. Если разработчик базового класса сделал свою реализацию — зачем вам лезть дальше в дебри дерева наследования, чтобы вытащить что-то оттуда из самого нутре? Мало ли зачем он его перегрузил — может он там состояние объекта своего меняет? А вы хотите в обход его реализации пойти.
Вот именно меняет. Только одна маленькая деталь, не своего объекта, а уже нашего общего. Могу же я у собственного объекта сам выбирать поведение. И это поведение уже на 80% реализовано в пред-базовом, а потом в базовом урезано. Да дело даже не в этом. В данной ситуации я не могу вызвать защищенный метод своего предка. Доступ к защищенным методам предка это мое законное право как наследника, а тут меня его лишают. Какого хрена? В чем тут логика или хотябы философия???
Здравствуйте, IvanM, Вы писали:
IM>Здравствуйте, Алексей Одинцов, Вы писали:
АО>>Здравствуйте, Dr_Sh0ck, Вы писали:
АО>>Это вопрос-то скорее философский. Если разработчик базового класса сделал свою реализацию — зачем вам лезть дальше в дебри дерева наследования, чтобы вытащить что-то оттуда из самого нутре? Мало ли зачем он его перегрузил — может он там состояние объекта своего меняет? А вы хотите в обход его реализации пойти.
IM>Вот именно меняет. Только одна маленькая деталь, не своего объекта, а уже нашего общего. Могу же я у собственного объекта сам выбирать поведение. И это поведение уже на 80% реализовано в пред-базовом, а потом в базовом урезано. Да дело даже не в этом. В данной ситуации я не могу вызвать защищенный метод своего предка. Доступ к защищенным методам предка это мое законное право как наследника, а тут меня его лишают. Какого хрена? В чем тут логика или хотябы философия???
в том же, почему и некоторые члены вашего предка вам недоступны (are private). Разработчик вашего базового класса сделал свою реализацию, деталей которой вы не знаете. Если позволить вам исключить из работы его функциональность — его (и ваш) класс станет вести себя неправильно. Если вам очень хочется вызвать Control.SomeMethod() — унаследуйтесь напрямую от него и повторите реализацию так как вам нравится, либо уж используйте базовый класс таким какой он есть.
Если же вы сами разработчик всех трех классов — значит учитесь правильнее проектировать иерархии классов.
Здравствуйте, Алексей Одинцов, Вы писали:
АО>Здравствуйте, IvanM, Вы писали:
IM>>Здравствуйте, Алексей Одинцов, Вы писали:
АО>в том же, почему и некоторые члены вашего предка вам недоступны (are private). Разработчик вашего базового класса сделал свою реализацию, деталей которой вы не знаете. Если позволить вам исключить из работы его функциональность — его (и ваш) класс станет вести себя неправильно. Если вам очень хочется вызвать Control.SomeMethod() — унаследуйтесь напрямую от него и повторите реализацию так как вам нравится, либо уж используйте базовый класс таким какой он есть.
АО>Если же вы сами разработчик всех трех классов — значит учитесь правильнее проектировать иерархии классов.
Я не говорю здесь про private, это совершенно другое, о них не пишут в документации, их вобще нет. Раз уж дело дошло до обсуждения вопросов проектирования, то мое мнение — любое дублирование кода (кода предка в наследнике в частности) ведет к проблемам при последующей поддержке в целостном состоянии. И тут любая разумная возможность повторного использования кода — благо. В данном случае, IMHO, ситуация разумная. По поводу иерархии
1. Не всегда мы можем все спроектировать сами, иногда это уже сделали за нас.
2. Идеальные иерархии в реальной жизни попадаются не всегда.
А что касается "вести себя неправильно", откуда такая уверенность, что непременно все начнет вети себя неправильно? Точно так же можно запретить доступ к защищеннвм полям класса. А вдруг мы их изменим и все начнет вести себя неправильно? Это паранойя а не логика.
реализация функции — её код — такая же private как и приватные члены класса. то, что вам доступно вызвать её не говорит о том, что вы можете делать предположения о её коде.
если вы сами проектируете иерархии — у вас есть выход.
если не сами — Вам придется следовать логике программиста создавшего для Вас базовый класс. Вам не нравится его логика — напишите свой класс со своей. Если это невозможно по каким-то причинам (например, вы вынуждены использовать его как базовый) — увы. придется выкручиваться.
Но логика в таком подходе есть. Не сказал бы что я её разделяю, но мне всего пару раз пришлось столкнуться с этим ограничичением, и не могу сказать что оно такое уж драконовское. В C# и шаблонов пока нет, ну и что теперь? Хотите писать как на C++ — пишите на C++. Или пишите в MS пусть сделают эту Вашу фичу. Я ей применение тоже найду, хоть пока и не считаю её такой уж нужной.
Здравствуйте, Алексей Одинцов, Вы писали:
АО>Но логика в таком подходе есть. Не сказал бы что я её разделяю, но мне всего пару раз пришлось столкнуться с этим ограничичением, и не могу сказать что оно такое уж драконовское. В C# и шаблонов пока нет, ну и что теперь? Хотите писать как на C++ — пишите на C++. Или пишите в MS пусть сделают эту Вашу фичу. Я ей применение тоже найду, хоть пока и не считаю её такой уж нужной.
Вобщем, понятна логика. Во первых, С++ это не C#, а во вторых, ООП это не то, что я о нем думаю. Но, в любом случае, спасибо за ответ!
Здравствуйте, IvanM, Вы писали:
IM>Вот именно меняет. Только одна маленькая деталь, не своего объекта, а уже нашего общего. Могу же я у собственного объекта сам выбирать поведение. И это поведение уже на 80% реализовано в пред-базовом, а потом в базовом урезано. Да дело даже не в этом. В данной ситуации я не могу вызвать защищенный метод своего предка. Доступ к защищенным методам предка это мое законное право как наследника, а тут меня его лишают. Какого хрена? В чем тут логика или хотябы философия???
public class A
{
private ArrayList _list;
public A()
{
Init();
}
protected virtual void Init()
{
_list = new ArrayList();
}
public virtual void Add(object item)
{
_list.Add(item);
}
}
public class B : A
{
private ArrayList _list2;
protected override void Init()
{
base.Init();
_list2 = new ArrayList();
}
public override void Add(object item)
{
base.Add(item);
_list2.Add(item);
}
}
public class C
{
protected override void Init()
{
((B)this).Init();
}
}
...
C c = new C();
c.Add(25); // Null reference exception
Попробуй через делегаты. В Delphi обычная практика через TMethod.
Через рефлектор или CreateDelegate найти адрес метода и вствить его в соответствующее поля делегата, а на место ссылки на объект this.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Через рефлектор или CreateDelegate найти адрес метода и вствить его в соответствующее поля делегата, а на место ссылки на объект this.
Не выйдет.
Делегат — не адрес метода, он намертво с объектом-владельцем метода связан. А как раз-таки ссылку на "объект-дедушку" вычислить не получится. Боюсь, что в VTBL текущего обекта даже упоминания нет про "дедушкин" метод. Такое пройдет только со статическим методом или если "дед" сам такой делегат вернет.
Здравствуйте, Dax, Вы писали:
Dax>Делегат — не адрес метода, он намертво с объектом-владельцем метода связан. А как раз-таки ссылку на "объект-дедушку" вычислить не получится. Боюсь, что в VTBL текущего обекта даже упоминания нет про "дедушкин" метод. Такое пройдет только со статическим методом или если "дед" сам такой делегат вернет.
Почему же, делегат как раз имеет списочную структуру типа TMethod. А вот как выдернуть ссылку на дедушкин метод это другая проблема. Если это не абстрактный класс или через неабстрактного наследника не перекрывающего этот метод адрес выдернуть метода выдернуть можно просто создав объект этого типа создать делегат с его методом и заменить ссылку на объект на this.
и солнце б утром не вставало, когда бы не было меня