И ещё один глупый вопрос про сишарп - видимость методов
Должен ведь быть способ реализовать следующее: есть несколько классов, унаследованных от одного базового, базовый определяет какой-то метод; этот метод не должен быть виден снаружи, но его должны уметь вызывать объекты этих классов друг у друга?безопасность нарушается, т.е. если сделать как ты хочешь, то получится что можно вызывать вообще любой протектед метод любого объекта (главное чтобы его класс не был finalized с помощью вспомогательного wrapper-а, наследованного от класса атакуемого объекта.
в C# разделение доступа идет, как по классам, так и по экземплярам - и это правильно.
ps
то, что ты хочешь - можно сделать, через вспомогательный protected static метод у BaseClass-а
получится что можно вызывать вообще любой протектед метод любого объекта (главное чтобы его класс не был finalized с помощью вспомогательного wrapper-а, наследованного от класса атакуемого объектаХм, действительно.
Я как-то раньше не воспринимал области видимости как защиту от взломщиков, скорее - как дополнительную помощь программисту.
то, что ты хочешь - можно сделать, через вспомогательный protected static метод у BaseClass-аКак-то трансанально
ВпрочемЮ я уже придумал, как обойтись вообще без этого.
Кстати, а через reflection злобному хакеру разве не удастся вызвать хоть private-метод?
Кстати, а через reflection злобному хакеру разве не удастся вызвать хоть private-метод?только если у него к тому же есть права на доступ к закрытым полям.
Да и вообще, я не вижу сакрального смысла заботиться именно о "защите" класса от неправильного использования и порчи внутреннего состояния. Я считаю, что если есть исходник, и есть недобросовестный программист который ХОЧЕТ испортить объект, то ему никакие ограничения это сделать не помешают.
Скорее, "защита" нужна для того, чтобы пользователи класса не могли испортить объект СЛУЧАЙНО, в рамках предоставляемого интерфейса. Тогда public - это интерфейс, предоставляемый пользователю, а protected - интерфейс, предоставляемый наследнику.
Если я не прав, сорри.
всегда можно создать класс DerivedClass, и из него вызвать inherited foo.Можно поподробнее?
Я считаю, что если есть исходник,Исходника нет, есть сторонняя либа в .net-бинарниках. Что дальше?
Скорее, "защита" нужна для того, чтобы пользователи класса не могли испортить объект СЛУЧАЙНО, в рамках предоставляемого интерфейса.Тогда становится непонятно, зачем нужна эта дополнительная защита по сравнению с PHP.
м-м-м, не нравится мне твое объяснение. В принципе, если стоит задача вызвать protected метод foo у некоего класса BaseClass, то всегда можно создать класс DerivedClass, и из него вызвать inherited foo.у своего собственнего экземпляра - да сможешь, но что тебе это даст?
у чужого экземпляра - нет, не получится.
Да и вообще, я не вижу сакрального смысла заботиться именно о "защите" класса от неправильного использования и порчи внутреннего состояния. Я считаю, что если есть исходник, и есть недобросовестный программист который ХОЧЕТ испортить объект, то ему никакие ограничения это сделать не помешают.в чем отличие твоей фразы от?:
Да и вообще, я не вижу сакрального смысла заботиться именно о "защите" web-приложения(программы) от неправильного использования и порчи внутреннего состояния. Я считаю, что если есть исходник, и есть недобросовестный пользователь который ХОЧЕТ испортить web-приложение, то ему никакие ограничения это сделать не помешают.я правильно все-таки понимаю, что ты считаешь, что целые приложения защищать надо?
но при этом считаешь, что отдельные объекты защищать не надо?
Я считаю, что если есть исходник, и есть недобросовестный программист который ХОЧЕТ испортить объектздесь надо отличать порчу от возможности вызвать неадекватного поведения.
возьмем, например, ОС - да, пользователь с урезанными правами - может сделать так, что он больше своей учетной записью нормально пользоваться не сможет (ну, и фиг с ним главное - чтобы он не мог порушить работу самой ОС, или других пользователей.
так же и с объектами.
идеальная программа - должна быть построена так же, чтобы программист мог запороть только свои экземпляры, но не мог запороть работу основной части, или других модулей/экземпляров.
соответственно хороший framework - это тот, который позволяет такое поведение сделать.
.net такое поведение обеспечивает.
самое главное, я считаю, что не должно быть разделение между человеком и кодом, все что может сделано человек, должно быть доступно из кода, и наоборот.
поэтому если, например, на сайте или в программе, мы имеем возможность руками вызвать какую-то функцию, то мы должно иметь возможность вызвать эту функцию из кода снаружи, а в идеале, иметь возможность добавить свой код внутрь программы, который будет иметь возможность эту функцию вызывать.
возьмем, например, этот сайт - здесь, например, есть возможность загружать свои клиентские скрипты, но ведь часто бывает нужна возможность загрузить свой серверный скрипт(плагин а вот здесь уже как раз и нужны именно жесткие права на доступ из одного объекта в другой.
но ведь часто бывает нужна возможность загрузить свой серверный скрипт(плагин а вот здесь уже как раз и нужны именно жесткие права на доступ из одного объекта в другой.Ага, унаследуем свой класс от DbConnection, передадим ему объект DbConnection, а он спросит oConnection.getPassword и выдаст на экран.
Ага, унаследуем свой класс от DbConnection, передадим ему объект DbConnection, а он спросит oConnection.getPassword и выдаст на экранне поможет.
передадим ему объект DbConnectionэто чужой объект, к protected членам которого у тебя нет доступа
и можно кстати просто запретить на уровне прав возможность обращения к DbConnection.
это чужой объект, к protected членам которого у тебя нет доступаЯ как раз про это, привожу примеры к твоей мысли
Если бы было PHP-like поведение, то такой пользователь узнал бы пароль для доступа к БД; а так - не узнает.
Впрочем, имхо, было бы более логично как-нибудь помечать при сборке все классы, как финальные, кроме тех, которые явно определены как расширяемые.
Потому что, когда мы пишем класс в редакторе, можно понимать расширяемость в двух смыслах - расширяемость в рамках того же модуля (это должно быть разрешено по умолчанию и расширяемость другими разработчиками в их модулях (а вот это уже по умолчанию должно быть, наверное, всё-таки запрещено).
Потому что, когда мы пишем класс в редакторе, можно понимать расширяемость в двух смыслах - расширяемость в рамках того же модуля (это должно быть разрешено по умолчанию и расширяемость другими разработчиками в их модулях (а вот это уже по умолчанию должно быть, наверное, всё-таки запрещено).для этого и существует CAS
т.е., имхо, не надо смешивать техническую "закрытость" объекта и административную.
техническая закрытость - это мы собираем железку на клею, или на винтах, монолитно или на штекерах.
административная - это вешаем замок или нет.
protected, private - это техническая "закрытость".
cas - это административная "закрытость".
и их не стоит смешивать.
только если у него к тому же есть права на доступ к закрытым полям.а можно здесь подробнее, что за права ему нужны?
а можно здесь подробнее, что за права ему нужны?данному куску кода должно быть выдано System.Security.Permissions.ReflectionPermission
я вот создаю класс с private полем в одной сборке, а потом свободно меняю его в другой, я както неправильно компилирую?
пример в студию!
public class Class2
{
string Msg;
public Class2(string msg)
{
Msg = msg;
}
}
Class2 c = new Class2;
Type t = c.GetType;
FieldInfo fi = t.GetField("Msg", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
fi.SetValue(c, "123");
string msg = (string)fi.GetValue(c);
а как это можно увидеть?например,
1. запустить программу из сетевой шары другого компьютера
2. запустить прогу, как аплет в браузере
3. явно настроить permissions
Оставить комментарий
kruzer25
Я как-то привык, что код видадолжен работать, потому что видимости в php совершенно фиолетово, какие там объекты, она обращает внимание на классы; а на классы он обращает внимание только в той степени, что приватный метод должен быть определён в том же классе, откуда мы его зовём; а protected - в том же или в одном из родительских.
А в сишарпе такое не работает:
При этом, если вместо this.obj.foo написать DerivedClass)this.obj).foo то всё работает (про что и говорит сообщение об ошибке).
Может быть, я пишу не те ключевые слова?
Должен ведь быть способ реализовать следующее: есть несколько классов, унаследованных от одного базового, базовый определяет какой-то метод; этот метод не должен быть виден снаружи, но его должны уметь вызывать объекты этих классов друг у друга?