¿Cómo puedo agregar dinámicamente un campo a una clase en C #

¿Hay alguna manera de agregar Field (o FieldInfo , tal vez esto es lo mismo) a una clase en tiempo de ejecución?

No puede alterar una definición de clase en tiempo de ejecución. Sin embargo, puede crear una nueva clase que herede de la clase original (si no está sealed ) y declara el campo. Puede hacerlo emitiendo el código IL apropiado utilizando System.Reflection.Emit .

C # no lo permite porque todas sus clases se basan en metadatos. El CLR (no C #) no permite la adición de campos a los metadatos en el tiempo de ejecución (1). Esta es la única forma en que C # podría agregar un campo en runitme.

Esto es diferente a los lenguajes dynamics como IronPython que esencialmente no tienen clases de metadatos concretas. Tienen estructuras más dinámicas que pueden alterarse en tiempo de ejecución. Creo que IronPython simplemente mantiene sus miembros (campos y métodos) en lo que equivale a una tabla hash que se puede modificar fácilmente en tiempo de ejecución.

En C # 3.0, su mejor recurso es usar Reflection.Emit. Pero esto generará una clase completamente nueva vs. la modificación de una existente.

(1) Existen ciertas API, como las API de generación de perfiles o ENC, que permiten esto, pero no estoy seguro si sus capacidades se amplían para agregar campos.

No, C # no permite el parche de monos .

Puede generar nuevas clases utilizando CodeDOM o Reflection.Emit, pero no puede modificar las existentes.

No exactamente.

Sin embargo, puede implementar ICustomTypeDescriptor para aproximarlo, y luego simplemente usar una tabla hash para almacenar los pares nombre / valor de campo. Gran parte del framework que usa reflection solicita primero ICustomTypeDescriptor.

No hasta C # 4.0, que agrega búsqueda dinámica y se basa en el CLR 4.0 que incorpora el DLR, y luego no se agregará estrictamente a una clase, ya que las clases no estarán en la imagen.

como otros dijeron, esto no es posible. ¿Cuál es el motivo de tu pregunta? Si necesita almacenar algunos datos adicionales en la clase dinámicamente, entonces probablemente podría simplemente usar el diccionario:

 class My { Dictionary data; public My() { data = new Dictionary(); } } 

.. pero realmente depende de lo que realmente quieres lograr?

Consulte esta pregunta para obtener una forma sencilla de hacerlo en C # 4.0, lanzando un ExpandoObject como IDictionary , lo que hace que los valores agregados al diccionario se conviertan en propiedades del objeto. Demuestro esto en otra respuesta mía que muestra que realmente se convierten en propiedades.

Sin embargo, esto solo es posible con una instancia de ExpandoObject o ExpandoObject DynamicObject .

También puede ser posible usarlo con otras clases si implementan IDynamicMetaObjectProvider , pero creo que hay mucho trabajo para que funcione correctamente.

Tal vez podrías usar el patrón Decorator.

En la progtwigción orientada a objetos, el patrón de decorador es un patrón de diseño que permite que el comportamiento se agregue a un objeto individual, ya sea estática o dinámicamente, sin afectar el comportamiento de otros objetos de la misma clase.

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