Добавить свойство, не касаясь класса?(не наследство) - PullRequest
4 голосов
/ 31 июля 2010

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

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

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

Существует ли более простая альтернатива?Это просто ненужная сложность?Может мне просто добавить новое свойство в мой класс?

Спасибо!

Ответы [ 6 ]

4 голосов
/ 31 июля 2010

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

2 голосов
/ 31 июля 2010

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

2 голосов
/ 31 июля 2010

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

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

0 голосов
/ 31 июля 2010

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

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

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

0 голосов
/ 31 июля 2010

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

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

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

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

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

0 голосов
/ 31 июля 2010

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

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