![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 2 Всего: 25 |
как известно, интерфейсы, в отличие от классов, не могут объявлять внутренние типы
в связи с этим у меня 2 проблемы. 1) Если мне нужен класс, в котором есть переменная состояния и функция, изменяющая это состояние, я делаю вот так: (попрошу не придираться к коду, ибо пишу для примера, может есть ошибки)
если для этого класса нужен интерфейс, то тип этот и функцию в интерфейсе я сделать не могу. Это первая проблема. 2) Вторая похожа на первую, только я не могу объявлять в интерфейсе делегаты для того, чтобы класс, унаследованный от интерфейса мог посылать сообщения тем, кто знает только об интерфейсе :( Застрял я на этом, когда стал читать известную книжку "Design Patterns". На С++ я смог "реализовать" некоторые из паттернов, а на шарпе, благодаря этому ограничению, не могу. Может, кто знает, как быть? |
|||
|
||||
| mihryak |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 731 Регистрация: 28.4.2007 Где: С-Пб Репутация: 19 Всего: 36 |
теперь, похоже, понял оба вопроса
и делегат, и энум можно вынести из класса Это сообщение отредактировал(а) mihryak - 4.9.2007, 14:20 |
|||
|
||||
| FREEDEV |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 238 Регистрация: 6.3.2007 Где: Украина->Одесс а Репутация: 1 Всего: 3 |
mihryak, так же делал, но все равно, кажется, что это как-то не корректно
--------------------
Microsoft Windows Visla © |
|||
|
||||
| SpaceSpace |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 366 Регистрация: 10.4.2007 Где: Самара Репутация: 2 Всего: 10 |
1.
для класса интерфейс
если тебе нужны поля - используй базовые классы 2. делегаты можно использовать из базовых классов Это сообщение отредактировал(а) SpaceSpace - 4.9.2007, 14:24 -------------------- Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение. 70-565 MCPD Enterprise 3.5 |
|||
|
||||
| mihryak |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 731 Регистрация: 28.4.2007 Где: С-Пб Репутация: 19 Всего: 36 |
||||
|
||||
| FREEDEV |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 238 Регистрация: 6.3.2007 Где: Украина->Одесс а Репутация: 1 Всего: 3 |
идея интерфейса такова, что, описывая его, мы не должны задумываться как будет реализован класс, полученный от него, и какие там типы будут использованы.
может я и не прав... Это сообщение отредактировал(а) FREEDEV - 4.9.2007, 14:50 --------------------
Microsoft Windows Visla © |
|||
|
||||
| mihryak |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 731 Регистрация: 28.4.2007 Где: С-Пб Репутация: 19 Всего: 36 |
ну вообще крайне редко интерфейсы ограничиваются базовыми типами данных, так что, так или иначе, они будут навязывать классам много особенностей и требований.
а внесённые в сам класс enum и delegate мне тоже не очень нравятся (причём в большей степени внешне, а не из-за нарушения концепции), но их можно безболезненно вынести из класса |
|||
|
||||
| Alek86 |
|
||||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 2 Всего: 25 |
в книге, о которой я говорил, написано, что класс является лишь одной из возможных реализаций того типа, который объявляет интерфейс. И нужно использовать указатели (в шарпе - объекты) именно на интерфейс, а не на класс, чтобы легко можно было подменить реализацию типа (то есть сам класс).
Наверно запутанно высказался. допустим тип:
можно реализовать как с помощью класса
так и с помощью класса:
как с помощью метода, который предложил mihryak в тип IPoint можно было бы добавить "виды" прорисовки точки (звездочкой его рисовать, или квадратом или еще как-то)
?? опять же, пример надуманный Это сообщение отредактировал(а) Alek86 - 4.9.2007, 15:11 |
||||||||
|
|||||||||
| mihryak |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 731 Регистрация: 28.4.2007 Где: С-Пб Репутация: 19 Всего: 36 |
ну так объяви в интерфейсе
вместо
а в методе Draw кейси по стилю рисования пс. решение такая же хрень, как и пример |
||||
|
|||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 2 Всего: 25 |
ну, получается очень плохо, ибо "вид" точки не инкапсулирован в саму точку и является совершенно отдельным типом, хотя нужен только там.
если подобных объектов будет много (прямоугольники, круги) и у каждого свои "виды", то нужно будет и EView переименовывать в EPointView, и, потом. будет банальное засорение глобального пространства имен. выход, конечно, есть - ввести и интерфейс точки и его реализации в свое пространство имен, и также поступать со всеми подобными объектами (и, кажется, придется так и сделать, хоть хорошего в этом вижу мало :( ) тогда последний в теме вопрос (может, кто знает) Для чего разработчики языка сделали невозможным объявление типов в интерфейсах? Чем это плохо? Это сообщение отредактировал(а) Alek86 - 4.9.2007, 15:50 |
|||
|
||||
| mihryak |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 731 Регистрация: 28.4.2007 Где: С-Пб Репутация: 19 Всего: 36 |
что-то какое-то месево
чтобы инкапсулировать вид в саму точку, сделай абстрактный класс для фигуры, объяви его реализующим интерфейс
Если посчиташь возможным/нужным реализуй SetCoord, а Draw оставь абстракным потом объяви наследника от этого абстрактного класса, например SquarePoint, метод Draw которого и будет рисовать квадратную точку при использовании в списках тебе достаточно будет знать, что это - просто какая-то штуковина, реализующая интерфейс, а как она себя будет рисовать - не имеет значения, ей виднее Таким образом, перечисление тут вообще не нужно и на последний вопрос - а нафига объявлять типы в интерфейсах? |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 2 Всего: 25 |
эх...
mihryak, рекомендую почитать Design Patterns, так подробно рассмотрены подобные проблемы и их нормальные решения ни в коем случае не хочу сказать, что твое решение плохое, но в нем, имхо, ты не учитываешь всех условий (к примеру, что методы Draw будут различаться не только для разных "видов", но и для разных систем (винда, линух)), а также возможность расширения. и, как говорилось там же,
а на я, кажется, ответил, что иначе |
|||
|
||||
| mihryak |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 731 Регистрация: 28.4.2007 Где: С-Пб Репутация: 19 Всего: 36 |
сдаюсь и жду "хорошое решение"
пс #1. с паттернами знаком, использую при целесообразности пс #2. даже если бы в интерфейсах можно было бы объявлять классы, они всё равно лежали бы в том же пространстве имён, что и сам интерфейс (при этом являясь общедоступными), чем не "засорение"? пс #3. не так давно спорили тут с SpaceSpace о делегатах, обсуждая подобное надуманное решение, пришли к выводу, что каков вопрос - такой и ответ. для более адекватно представленной проблемы, скорее всего, нашлось бы и более адекватное решение, делать выводы о неудобной декларации интерфейсов .Net, исходя из невозможности рисовать звёздообразные точки в линуксе, право слово, не стоит Это сообщение отредактировал(а) mihryak - 5.9.2007, 10:08 |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 2 Всего: 25 |
ответ на ПС №2
они бы лежали в самом интерфейсе, и чтоб обратиться к их названиям, нужно было бы приписать к ним спереди название интерфейса с точкой, и не выдумывать уникальные для неймспейса имена. красиво сказано Приведу пример из жизни есть интерфейс, некоторые функции которого могут возвращать не false в случае ошибки, а саму ошибку (нужно заметить, что коды ошибок, равно как и их значения нужны только при использовании этого интерфейса и его всех возможных реализаций) ошибки, как я считаю, нужно кодировать через enum. Функции должны возвращать код ошибки (т.е. элемент enum'а). на сях я (и не раз так уже делал) в классе-интерфейсе создавал энам, а также нужные мне чисто виртуальные функции. как нужно это делать на шарпе? ЗЫ. Вопрос
подразумевал: "зачем эту возможность убрали (по сравнению с С++), а не почему не добавили?" Это сообщение отредактировал(а) Alek86 - 4.9.2007, 22:56 |
|||
|
||||
| SpaceSpace |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 366 Регистрация: 10.4.2007 Где: Самара Репутация: 2 Всего: 10 |
хочу заметить что решения в паттернах отнюдь не нормальные, это шаблонные решения. В некоторых случаях от намеченного в начале паттерна остаются рожки да ножки. -------------------- Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение. 70-565 MCPD Enterprise 3.5 |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |