1) Одна из причин использования инкапсуляции заключается в том, что, скрывая внутренние детали реализации, мы можем изменять эти детали, не нарушая существующий код - это имеет смысл
a) Но я не понимаю аргументаэта инкапсуляция должна использоваться для того, чтобы пользователи не могли перевести внутренние данные объекта в недопустимое или незавершенное состояние.
Если я напишу класс и продам его другим программистам (которые реализуют этот класс в своих собственных)приложения), не должны ли они нести ответственность за правильный доступ к этому объекту?В конце концов, если они не используют объект правильно, то только его приложения пострадают из-за этого.
Аналогия (плохая) того, что мне приходится реализовывать инкапсуляцию ради других программистов, не переводящих внутренние данные (случайно или преднамеренно) в незаметное состояние, будет продавать водонепроницаемые телевизоры на случай, если покупателирешили плавать со своими телевизорами.
2) С
http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx
void Foo(Giraffe g) {}
void Bar(Animal a) {}
Action<Mammal> action1 = Foo; // illegal
Action<Mammal> action2 = Bar; // legal
Почему первое присвоение является незаконным?Потому что вызывающий action1 может передать Тигра, но Фу не может взять Тигра, только Жирафа!Второе назначение является законным, потому что Бар может взять любое животное. «
Я понимаю аргументацию автора о том, почему Action<Mammal> action1
не может быть в состоянии принять Foo()
.Но с другой стороны, не должно ли быть обязанностью программиста не передавать в делегат аргументы, которые не могут обрабатывать зарегистрированные методы?
Таким образом, если какой-то программист регистрирует метод Foo, то они также будут знать:
• не вызывать action1
делегата с чем-либо кроме, чем с Giraffe
аргументом
• Не регистрировать методы с сигнатурой, отличной от Foo
(кроме случаев, когда метод определяет в качестве своего параметра aтип, из которого Mammal
происходит)
thanx