Здравствуйте, _FRED_, Вы писали:
_FR>А почему, собвтвенно, запретили фичу?
Прикольно.
Надо полагать, не додумались до такого сценария. Или сочли, что он слишком сложен в реализации — смотри, при анализе кода достаточно легко сопоставить private и abstract. В случае отсутствия вложенных классов, такое сочетание однозначно является ошибкой.
В случае наличия вложенных классов, где ни один из них не перегружает наш метод, сочетание по-прежнему является ошибкой.
Надо будет при случае спросить Эрика на эту тему.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>В случае наличия вложенных классов, где ни один из них не перегружает наш метод, сочетание по-прежнему является ошибкой. S>Надо будет при случае спросить Эрика на эту тему.
Вдогонку:
abstract class C
{
private abstract void M();
private abstract class D : C
{
private sealed class E : D
{
private override void M() { }
}
}
}
"По мере нарастания уровня маразма, сложность анализа быстро стремится к бесконечности".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
_FR>>А почему, собвтвенно, запретили фичу? S>Прикольно. S>Надо полагать, не додумались до такого сценария. Или сочли, что он слишком сложен в реализации — смотри, при анализе кода достаточно легко сопоставить private и abstract. В случае отсутствия вложенных классов, такое сочетание однозначно является ошибкой. S>В случае наличия вложенных классов, где ни один из них не перегружает наш метод, сочетание по-прежнему является ошибкой.
Такой анализ, кажется, даже не нужен: если нет вложенных классов-наследников, то экземпляр "легально" создать нельзя. Но в качестве ворнинга пригодилось бы.
S>Надо будет при случае спросить Эрика на эту тему.
Тут более-менее понятно: данный неподдерживаемый функционал целиком покрывается этим вот рабочим:
class C
{
private C() { }
// Несанкционированных наследников
// у класса с private-конструктором
// не будет, поэтому можно сделать protectedprotected virtual void M() { }
class D : C // Доступ к приватным конструкторам-то есть
{
protected override void M() { }
}
}
Но странным не показалось то, что запрет на сабж не получился как следствие, а был введён намеренно, то есть (как любит говорить сам Эрик) "because no one ever designed, specified, implemented, tested, documented and shipped that feature…", не смотря на то, что запрещаемая функциональность [на мой простой взгляд] не противоречит дизайну языка.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали: _FR>Такой анализ, кажется, даже не нужен: если нет вложенных классов-наследников, то экземпляр "легально" создать нельзя.
Ну и что?
Даже если они есть, нет никакой гарантии, что экземпляр всё еще можно создать.
_FR>Тут более-менее понятно: данный неподдерживаемый функционал целиком покрывается этим вот рабочим: _FR>
_FR>class C
_FR>{
_FR> private C() { }
_FR> // Несанкционированных наследников
_FR> // у класса с private-конструктором
_FR> // не будет, поэтому можно сделать protected
_FR> protected virtual void M() { }
_FR> class D : C // Доступ к приватным конструкторам-то есть
_FR> {
_FR> protected override void M() { }
_FR> }
_FR>}
_FR>
_FR>Но странным не показалось то, что запрет на сабж не получился как следствие, а был введён намеренно, то есть (как любит говорить сам Эрик) "because no one ever designed, specified, implemented, tested, documented and shipped that feature…", не смотря на то, что запрещаемая функциональность [на мой простой взгляд] не противоречит дизайну языка.
Не очень понятно. Запрещён совершенно конкретный сценарий. К сожалению, под него, помимо очевидно ошибочных случаев, случайно попадают и редкие "рабочие".
Какое решение ты предлагаешь — отказаться от этого еррора совсем, понизив его до ворнинга?
Сделать его ворнингом в случае наличия вложенных классов-наследников, оставив ошибкой в противном случае?
Сделать его ошибкой, если транзитивное замыкание всех вложенных классов-наследников не включает в себя ни одного неабстрактного?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, _FRED_, Вы писали:
_FR>А почему, собвтвенно, запретили фичу?
_FR>
_FR>abstract class C
_FR>{
_FR> private abstract void M();
_FR> private sealed class D : C
_FR> {
_FR> private override void M() { }
_FR> }
_FR>}
_FR>
Забавно, ну уж весьма спецефический сценарий. Врядли кто либо расстроился из-за отсутвия данной фичи, а комплиер и спеки стали проще.
Да и нарушается таки private, всё же через наследование class D не должен видеть M(). Через то, что он внутри неймспейса класса он этот метод видит, а через наследование нет — т.е. не может перегрузить.
Здравствуйте, master_of_shadows, Вы писали:
__>Забавно, ну уж весьма спецефический сценарий. Врядли кто либо расстроился из-за отсутвия данной фичи, а комплиер и спеки стали проще.
Стал ли проще компилятор — не уверен. И на счёт спеки тоже — что описывать ошибку компиляции, что описывать поведение — количество информации, ИМХО, одно и то же. Да и дай нам обеднеть на столько, что бы определять необходимость фичи по размер спецификации для её описания ;о)
__>Да и нарушается таки private, всё же через наследование class D не должен видеть M().
D и сейчас видит закрытые члены базы
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
__>>Забавно, ну уж весьма спецефический сценарий. Врядли кто либо расстроился из-за отсутвия данной фичи, а комплиер и спеки стали проще.
_FR>Стал ли проще компилятор — не уверен. И на счёт спеки тоже — что описывать ошибку компиляции, что описывать поведение — количество информации, ИМХО, одно и то же. Да и дай нам обеднеть на столько, что бы определять необходимость фичи по размер спецификации для её описания ;о)
Так ошибка то ведь останется, даже если ввести такое вот исключительное поведение. Компилер ругается на private abstract/virtual.
__>>Да и нарушается таки private, всё же через наследование class D не должен видеть M().
_FR>D и сейчас видит закрытые члены базы
Выделил ключевой момент. Мы же пытаемся перегрузить метод, а не просто дёрнуть его. Хотя вот к конструктору есть доступ ...
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, _FRED_, Вы писали: _FR>>Такой анализ, кажется, даже не нужен: если нет вложенных классов-наследников, то экземпляр "легально" создать нельзя. S>Ну и что? S>Даже если они есть, нет никакой гарантии, что экземпляр всё еще можно создать.
А такая гарантия и не нужна: например, компилятору, мне кажется, совсем не надо ругаться — а он и не ругается — на такой вот класс:
class C
{
private C() { }
}
хотя пользы от него тоже не много.
_FR>>Но странным не показалось то, что запрет на сабж не получился как следствие, а был введён намеренно, то есть (как любит говорить сам Эрик) "because no one ever designed, specified, implemented, tested, documented and shipped that feature…", не смотря на то, что запрещаемая функциональность [на мой простой взгляд] не противоречит дизайну языка. S>Не очень понятно. Запрещён совершенно конкретный сценарий. К сожалению, под него, помимо очевидно ошибочных случаев, случайно попадают и редкие "рабочие".
Не ясно, почему запрещён. Мне видится одна причина — не было найдено ни одного удовлетворительного сценария использования. Есть ли другие причины? Если нет, то зачем позволили виртуальные field-like события? Вот с ними точно ничего хорошего не добиться — больше ошибок наделаешь.
S>Какое решение ты предлагаешь — отказаться от этого еррора совсем, понизив его до ворнинга?
Да, можно было бы просто разрешить безо всяких ошибок-ворнингов-анализов: потому что никакого вреда [пока nikov нам не показал обратного ] данная фича не причиняет и говорит лишь о скорее всего (без использования inner-наследников) бессмысленности действий програмиста, но не об ошибке с его стороны. Смотри пример в начале сообшения: так же бессмысленно, но с точки зрения компилятора верно.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, master_of_shadows, Вы писали:
__>>>Да и нарушается таки private, всё же через наследование class D не должен видеть M(). _FR>>D и сейчас видит закрытые члены базы __>Выделил ключевой момент. Мы же пытаемся перегрузить метод, а не просто дёрнуть его. Хотя вот к конструктору есть доступ ...
Даже сейчас возможно такое:
class C
{
protected virtual void M() { }
private void M2() { }
class D : C
{
protected override void M() { M2(); }
}
}
то есть вызов из наследника закрытого члена базового класса. Так почему нельзя разрешить перегрузку?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>то есть вызов из наследника закрытого члена базового класса. Так почему нельзя разрешить перегрузку?
Ну да, вызов (и не только, ещё доступ к полям и т.д.) возможен, но нельзя через перегрузку добраться. Полагаю при перегрузке компилер проверяет совсем другие условия. А почему нельзя: рубанули вообще private virtual, ибо не увидели внятных сценариев .
Как вариант work around-а можно использовать internal .
Здравствуйте, master_of_shadows, Вы писали:
__>Ну да, вызов (и не только, ещё доступ к полям и т.д.) возможен, но нельзя через перегрузку добраться.
Этот момент не понял. Ты предлагаешь новый уровень доступа, который включает private, но не включает protected? Или описываешь некое поведение компилятора, которого я не понимаю?
Приведи пример кода, о котором ты говоришь.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, master_of_shadows, Вы писали:
__>>Ну да, вызов (и не только, ещё доступ к полям и т.д.) возможен, но нельзя через перегрузку добраться. S>Этот момент не понял. Ты предлагаешь новый уровень доступа, который включает private, но не включает protected? Или описываешь некое поведение компилятора, которого я не понимаю? S>Приведи пример кода, о котором ты говоришь.
Я говорю о двух вещах (грубо говоря повторение того, что тут и обсуждалось):
1. Вложенный класс может дораться до private мемберов внешнего к нему класса.
2. Но перегрузить те же private мемберы внешнего и родительского к нему класса не может.
Не знаю откуда ты вывел ещё один модификатор доступа .
class A
{
private void M() {}
private virtual void M2() {}
private int _f;
class B : A
{
B() { M(); _f = 1; } //Можно добраться.override void M2() {} //А тут нет.
}
}
Здравствуйте, master_of_shadows, Вы писали:
__>Я говорю о двух вещах (грубо говоря повторение того, что тут и обсуждалось): __>1. Вложенный класс может дораться до private мемберов внешнего к нему класса. __>2. Но перегрузить те же private мемберы внешнего и родительского к нему класса не может. __>Не знаю откуда ты вывел ещё один модификатор доступа .
Всё, я протупил. Понятно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Константин Л., Вы писали:
_FR>>D и сейчас видит закрытые члены базы
КЛ>как и с++
В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, Константин Л., Вы писали:
_FR>>>D и сейчас видит закрытые члены базы
КЛ>>как и с++
_FR>В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, Константин Л., Вы писали:
_FR>>>D и сейчас видит закрытые члены базы
КЛ>>как и с++
_FR>В С++ больше: есть прекрасная возможность сделать override private-методу Правда, и обломиться можно из-за того, что override не нужно писать, но всё-таки.