2010-07-31 4 views
4

У меня есть требование в моем проекте добавить другое свойство в какой-то класс. Теперь я хочу избежать изменения класса, потому что я решил, что он не должен знать, что у него есть это свойство (это свойство имеет значение только в контексте этого проекта).Добавление свойства, не касаясь класса? (не наследование)

Как я думал, что для достижения этой цели была (Пожалуйста, критик, потому что я хочу знать, если есть более простые способы сделать это)

  1. Добавлением нового одноэлементного класса, который имеет соответствие между объектами моего класса и тип свойства, которое я хотел добавить
  2. добавление в этот класс метода расширения (свойство расширения?) для доступа к отображению и выборка свойства.

Есть ли более простая альтернатива? Это просто лишняя сложность? Может быть, мне нужно добавить новое свойство в мой класс?

Спасибо!

+0

Как писал Дэн Брайант, это не редкость делать такое, и у него много хороших преимуществ. Я бы создал get-и set-ExtensionMethod для вашего типа (свойства расширения не существуют) и сохранить значения в статической хэш-таблице (Dictionary), где ваш объект является ключом для хеш-таблицы. Недостатком этого является то, что у вас нет свойств. Если вы хотите иметь это, вы должны принять другое решение (например, композит). – HCL

ответ

4

Дизайн, который вы описали, фактически тот, который используется Microsoft для реализации системы DependencyProperty и, в частности, Attached Properties, хотя и в более широком контексте инфраструктуры привязки.Тем не менее, использование словаря со «прикрепленными» данными является очень типичным решением, когда вам нужно пометить класс дополнительным контекстом для конкретного использования, но не хотите изменять класс.

0

Метод расширения имеет смысл, и это также относительно просто.

[visibility] [type] [methodName](this [class to extend] c, ... more args if necessary) 
{ 
.... 
} 
+0

Но статический метод расширения не работает как свойство класса. –

+0

Методы расширения являются статическими и должны быть членами статического класса. Это ограничивает их способность хранить информацию о состоянии любого рода; обычно лучше всего рассматривать методы расширения как апатриды (т. е. они не могут действовать как свойства). –

2

Почему вы говорите «не наследование»? Конечно, способ сделать это, если вы не хотите изменять оригинальный класс, должен был наследовать от исходного класса, а затем добавить ваше свойство в производный класс?

BTW, есть только методы расширения, а не свойства, поэтому вы не можете сделать это через свойство.

+1

Я могу представить много случаев, когда наследование невозможно или не имеет смысла, из-за того, что на создание объекта нельзя влиять (например, при работе с некоторыми ORM). Композиция часто является опцией. – HCL

0

Добавление свойства не нарушает взаимодействия класса с существующими клиентами, так что это действительно кажется «самым простым».

Важнее, однако, функция нового свойства. Является ли это логически частью существующего класса? Измените класс. Если нет, то предпочтительным может быть метод расширения, но тогда проблема становится видимостью метода расширения и объема его клиентов.

Как всегда, сложность - это враг. В этом случае звучит так, как будто синглтон является очень сложным решением, а метод расширения - «промах» и «промах» в зависимости от объема и проблем с визуальностью. Изменение класса является самым простым и, вероятно, облегчит долгосрочное обслуживание.

ОБНОВЛЕНИЕ: Обратите внимание, что методы расширения являются статическими, и это затрудняет метод расширения для хранения данных любого времени, так как свойство было бы выполнено.

ВТОРОЕ ОБНОВЛЕНИЕ: Если у вас есть доступ к источнику для класса, рассмотрите возможность его частичного класса и поместите новое свойство в отдельный файл, но часть того же частичного класса. Это позволяет отделить его от основной части класса для целей технического обслуживания и будет работать с большинством ORM. Однако существует ограничение на то, что частичные члены класса должны быть в одной сборке.

2

Я бы предложил образец ДЕКОРАТОРА. Я знаю, вы говорите, что не хотите использовать наследование, но иногда это чище. Для определения интерфейса шаблон использует только наследование.

0

Определение обнуляемого значения их свойств (в то время как свойство имеет значение только для этого проекта)

ваша главная проблема в том, что вы не хотите, чтобы изменить сам класс, потому что это требование ТОЛЬКО 1 проекта (сборки), я думаю, что вы рассматриваете SOLID priniciples, один из этих принципов OCP (Open-Closed принцип), то есть,

ваш объект должен быть открыт для расширения но закрыты для модификации

Смежные вопросы