Как я могу динамически добавлять поле в класс в С#

Есть ли способ добавить Field (или FieldInfo, может быть, это то же самое) к классу во время выполнения?

Ответ 1

Вы не можете изменить определение класса во время выполнения. Однако вы можете создать новый класс, который наследует от исходного класса (если он не sealed) и объявляет это поле. Вы можете сделать это, испустив соответствующий IL-код, используя System.Reflection.Emit.

Ответ 2

Нет, С# не разрешает обезвреживание обезьян.

Вы можете создавать новые классы, используя либо CodeDOM, либо Reflection.Emit, но вы не можете изменять существующие.

Ответ 3

С# не позволяет этого, потому что все его классы основаны на метаданных. CLR (не С#) запрещает добавление полей в метаданные во время выполнения (1). Это единственный способ, которым С# мог бы добавить поле в runitme.

Это не похоже на динамические langauges, такие как IronPython, которые по существу не имеют конкретных классов метаданных. Они имеют более динамические структуры, которые могут быть изменены во время выполнения. Я считаю, что IronPython просто сохраняет его членами (полями и методами) в том, что составляет хэш-таблицу, которую можно легко изменить во время выполнения.

В С# 3.0 ваш лучший ресурс - использовать Reflection.Emit. Но это создаст совершенно новый класс и изменит существующий.

(1) Существуют определенные API, такие как API профилирования или ENC, которые позволяют это, но я не уверен, что их возможности расширяются до добавления полей.

Ответ 4

Не совсем.

Однако вы можете реализовать ICustomTypeDescriptor для его приближения, а затем просто использовать хэш-таблицу для хранения пар имя/значение. Многие рамки, использующие отражение, сначала запрашивают ICustomTypeDescriptor.

Ответ 5

Пока С# 4.0, который добавляет динамический поиск и основан на CLR 4.0, который включает DLR, а затем он не будет строго добавляться к классу, поскольку классы не будут отображаться.

Ответ 6

как уже говорили другие, это невозможно. В чем причина вашего вопроса? Если вам нужно хранить некоторые дополнительные данные в классе динамически, то вы, вероятно, можете просто использовать словарь:

class My { 
   Dictionary<string, object> data;
   public My() { data = new Dictionary<string, object>(); }
}

.. но это действительно зависит от того, чего вы на самом деле хотите достичь?

Ответ 7

См. этот вопрос для простого способа сделать это в С# 4.0, выполнив ExpandoObject как IDictionary, что приводит к добавлению значений в словарь, чтобы стать свойствами объекта. Я демонстрирую это в еще одном моем ответе, показывающем, что они фактически становятся собственностью.

Однако это возможно только с экземпляром ExpandoObject или путем подклассификации DynamicObject.

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

Ответ 8

Возможно, вы можете использовать шаблон Decorator.

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

http://www.dofactory.com/Patterns/PatternDecorator.aspx