Добавить метаданные, связанные с конкретным полем, когда я присваиваю значение полю класса? - PullRequest
3 голосов
/ 06 апреля 2011

У меня есть класс, и я делаю некоторые изящные вещи с отражением.

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

Я хотел бы сделать это, чтобы клиенты не знали о моей реализации (делать что-то свое).

Наличие обозначенного «мета» поля или объекта в классе будет работать, но не очень элегантно, так как требует, чтобы дочерний класс сделал что-то «совместимое». Я хотел бы динамически присоединить эту метаинформацию к существующему классу, но все же позволить обрабатывать ее как тот же класс, что и остальная часть приложения. Я хотел бы иметь возможность восстановить эту мета-информацию позже.

  • Класс передается в
  • Значения присваиваются (отображаются) через Reflection с Мета-информация прилагается
  • Класс возвращен

* Этот процесс не должен иметь побочных эффектов в отношении обычных операций и типа объекта класса. Для общего применения класс должен быть одинаковым до и после.

  • Приложение «нормально» работает с классом (присваивает значения, получает значения, проверяет информацию и т. Д.)
  • Класс возвращается позже
  • Используйте значения вместе с метаинформацией, чтобы что-то сделать

Разобравшись с простейшими терминами, я, в основном, ищу способ "дополнить" дополнительную информацию о любом произвольном экземпляре класса без специальной модификации во время компиляции.

Я понимаю, что это странная проблема с некоторыми странными ограничениями, но можно ли это сделать?

Ответы [ 2 ]

6 голосов
/ 06 апреля 2011

Это применимо, если вам нужно дополнительное состояние для каждого типа, а не для экземпляра.

Лучше всего использовать собственный атрибут для поля.

1) Создайте атрибут:

[AttributeUsage(AttributeTargets.Field)]
public class MyCustomAttribute : Attribute
{

}

2) Украсьте поле:

class MyClass
{
    [MyCustomAttribute]
    private int _myField;
    ....

}

3) А затем в своем отражении:

if(fieldInfo.GetCustomAttributes(typeof(MyCustomAttribute), true).Length>0)
{
   ...
}

Если оно должно быть вЭкземпляр

Если данные должны быть частью экземпляра, тогда

  • любой экземпляр должен допускать его хранение.
  • Состояние должно храниться в отдельном классе, напримерсловарь

Второй подход - это тот, который первым приходит на ум и сразу же делает.На первой ноте можно

  • Определить состояние как отдельное свойство , которое может содержать информацию.Это тот, который вы предложили, и вас это не устраивает.
  • Наследовать от базового класса, который предоставляет дополнительную функциональность
  • Создать универсальный тип , например Metadata<T>, который предоставит такую ​​функциональность всем типам

Мне нравится третий, который может инкапсулировать, отражая тип T и создавая необходимые заполнители для хранения дополнительного состояния.Основная проблема заключается в том, что вы не можете передать тип методам в качестве параметра. Кажется, что второе решение является наиболее практичным.

1 голос
/ 06 апреля 2011

Я был бы склонен создать словарь с экземплярами объекта в качестве ключей и метаданными в качестве значений.Возможно, вам нужно быть осторожным, чтобы убедиться, что равенство определяется с помощью ReferenceEquals (), а не Equals ().Вам также может понадобиться составной ключ, содержащий объект и соответствующую PropertyInfo.

Этот подход также не будет работать, если метаданные должны следовать за объектом в некотором контексте, где словарь метаданных недоступен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...