Tengo una clase que se ve así:
public class Field
{
public string FieldName;
public string FieldType;
}
Y un objeto List<Field>
con valores:
{"EmployeeID","int"},
{"EmployeeName","String"},
{"Designation","String"}
Quiero crear una clase que se vea así:
Class DynamicClass
{
int EmployeeID,
String EmployeeName,
String Designation
}
¿Hay alguna forma de hacer esto?
Quiero que esto se genere en tiempo de ejecución. No quiero un archivo CS físico que resida en mi sistema de archivos.
c#
.net
reflection.emit
dynamic-class-creation
ashwnacharya
fuente
fuente
System.ServiceModel.ChannelFactory<MyDynamicInterface>
Respuestas:
Sí, puedes usar el
System.Reflection.Emit
espacio de nombres para esto. No es sencillo si no tienes experiencia con él, pero ciertamente es posible.Editar: este código puede ser defectuoso, pero le dará la idea general y, con suerte, tendrá un buen comienzo hacia el objetivo.
fuente
Tomará algo de trabajo, pero ciertamente no es imposible.
Lo que he hecho es:
Microsoft.CSharp.CSharpCodeProvider
(CompileAssemblyFromSource)Activator.CreateInstance
)De esta forma, puede manejar el código C # que ya conoce, en lugar de tener que emitir MSIL.
Pero esto funciona mejor si su clase implementa alguna interfaz (o se deriva de alguna clase base), de lo contrario, ¿cómo es que el código de llamada (léase: compilador) debe saber sobre esa clase que se generará en tiempo de ejecución?
fuente
También puede crear dinámicamente una clase utilizando DynamicObject .
Almaceno todos los campos de clase en un diccionario
_fields
junto con sus tipos y valores. Ambos métodos pueden obtener o establecer el valor de algunas de las propiedades. Debe usar ladynamic
palabra clave para crear una instancia de esta clase.El uso con su ejemplo:
Editar: Y así es como se ve mi clase
Field
:fuente
dynamic obj = new DynamicClass(fields){EmployeeId=123456;EmployeeName = "John"; Designation = "Tech Lead";}
, sería realmente genial hacer esto.Sé que reabrí esta antigua tarea, pero con c # 4.0 esta tarea es absolutamente indolora.
para más información, consulte https://www.oreilly.com/learning/building-c-objects-dynamically
fuente
No sé el uso previsto de tales clases dinámicas, y se puede hacer la generación de código y la compilación del tiempo de ejecución, pero requiere un poco de esfuerzo. Quizás los tipos anónimos te ayudarían, algo como:
fuente
Field.FieldName
. Tener que codificar los nombres de los campos invalida el propósito. Si tiene que hacer eso, también podría crear la clase.Quieres mirar CodeDOM . Permite definir elementos de código y compilarlos. Citando MSDN:
fuente
Según la respuesta de @ danijels, cree dinámicamente una clase en VB.NET:
fuente
También puede crear dinámicamente una clase utilizando DynamicExpressions .
Dado que 'Dictionary's tiene inicializadores compactos y maneja colisiones clave, querrás hacer algo como esto.
O puede que desee utilizar un convertidor JSON para construir su objeto de cadena serializada en algo manejable.
Luego usando System.Linq.Dynamic;
El resto es solo usar System.Reflection.
fuente
Para aquellos que desean crear una clase dinámica solo propiedades (es decir, POCO), y crear una lista de esta clase. Usando el código proporcionado más adelante, esto creará una clase dinámica y creará una lista de esto.
Aquí están las clases que usa el código anterior.
Nota: También deberá hacer referencia a la biblioteca Microsoft.CodeAnalysis.CSharp.
fuente
Puede ver el uso de módulos dinámicos y clases que pueden hacer el trabajo. La única desventaja es que permanece cargada en el dominio de la aplicación. Pero con la versión de .NET framework utilizada, eso podría cambiar. .NET 4.0 admite ensamblajes dinámicos coleccionables y, por lo tanto, puede recrear las clases / tipos dinámicamente.
fuente
¡Guauu! ¡Gracias por esa respuesta! Le agregué algunas características para crear un convertidor de "tabla de datos a json" que comparto con usted.
Y en "compileresulttype" sub, cambié eso:
fuente
Puede usar System.Runtime.Remoting.Proxies.RealProxy. Le permitirá usar código "normal" en lugar de cosas de tipo ensamblaje de bajo nivel.
Vea la respuesta de RealProxy a esta pregunta para un buen ejemplo:
¿Cómo intercepto una llamada al método en C #?
fuente
Runtime Code Generation with JVM and CLR
- Peter SestoftTrabaje para personas que estén realmente interesadas en este tipo de programación.
Mi consejo para ti es que si declaras algo, intenta evitar la cadena, por lo que si tienes clase Field, es mejor usar la clase System.Type para almacenar el tipo de campo que una cadena. Y en aras de las mejores soluciones en lugar de crear nuevas clases, intente utilizar las que se han creado FiledInfo en lugar de crear nuevas.
fuente