2009-05-22 11 views
7

Utilizando la sintaxis de C# inicializador de objeto que pueda crear una instancia de un objeto anónimo de esta manera:Crear instancias de objeto anónimo utilizando la sintaxis de inicializador # objeto C almacenado en cadena

object empData = new { name = "bob", age = 30, salary = 100000 }; 

Pero lo que si tengo el inicializador almacenado en una cadena, por ejemplo:

string init = "{ name = \"bob\", age = 30, salary = 100000 }"; 

¿Cuál es la mejor manera de convertir esta cadena en una instancia del objeto?

Respuesta

16

Las clases anónimas son C# syntactic sugar (ver la sección de comentarios here). csc.exe crea una clase con campos privados y una propiedad de lectura/escritura con el tipo deducido del contexto. Todos los usos del objeto son, de nuevo, inferidos.

Lo que esto significa es que no puede crear una clase anónima en tiempo de ejecución porque el CLR no los ve de manera diferente que cualquier otra clase (una vez más, porque es azúcar sintáctico C#).

Así que en lugar:

  • Utilice un Dictionary<string,object>
  • Uso JSON.NET, XML o algo por el estilo que tiene algún esquema ya definido para analizar una cadena para obtener un objeto. Esto requiere que las propiedades estén bien definidas, sin embargo.
  • System.Reflection.Emit uso para crear el tipo en tiempo de ejecución, pero no veo ningún beneficio real a este sobre sólo un Dictionary<string,object>

También tengo preocupaciones de lo que está haciendo porque esto como una cadena de medios muy probables para mí que está aceptando la entrada del usuario de algún tipo. Tenga cuidado con los problemas de seguridad en lo que sea que haga.

+0

Argh ... tienes razón, sabía que las clases se generaban en tiempo de compilación, pero mi cerebro no hizo la conexión (supongo que el largo fin de semana está atrasado). También su preocupación sobre la seguridad y la entrada del usuario es definitivamente válida. De todos modos, la razón por la que estaba haciendo esto es porque la API que estaba llamando tomó un objeto anónimo. Pero resulta que también puedo pasar un Dictionary para que resuelva el problema por mí. Gracias. – DSO

+0

Estoy totalmente de acuerdo. Me gusta usar mucho XML utilizando la reflexión para crear un complejo XML personalizado. No es para todos, pero si está haciendo XML simple, entonces usar la serialización .NET XML debería ser suficiente: D – pqsk

2

No hay una manera directa y sencilla de hacerlo. Básicamente, tiene estas opciones:

  1. Analice la cadena manualmente.
  2. Utilice el compilador C# para compilar ese objeto como parte de un ensamblaje y use la reflexión para descubrir el contenido.
  3. (no estoy seguro de si es posible, C# 4.0 solamente): utilice clases de compilador administradas C# 4.0 para analizar la expresión e inferir las cosas.

Ninguno de los cuales es ideal en mi opinión. Consideraría QueryString como pares, XML o JSON u otro formato que tenga analizadores disponibles en su lugar si tiene la opción y considera almacenar datos en una instancia de diccionario en lugar de crear un objeto para cada expresión.

1

No creo que esta pregunta respuestas la suya per se, pero a decir por qué no es posible crear instancias anónimas de los objetos que utilizan cuerdas de una manera tal como ha sugerido:

How do I create and access a new instance of an Anonymous Class passed as a parameter in C#?

Los tipos anónimos no tienen campos públicos, por lo tanto, aunque puede hacer esto para un objeto nombrado, no es tan sencillo hacerlo para un tipo anónimo. Dicho esto, no hay nada que lo detenga (como lo sugiere BFree) utilizando el reflejo para emitir el MSIL para el tipo anónimo, que no es exactamente sencillo, pero tampoco imposible.

3

La mejor manera de hacerlo es usar la serialización. Pero, por supuesto, eso no usa el mismo formato de cadena que describiste.

Su inicializador de objeto no tiene que contener valores constantes.

string myName="bob"; 
int myAge=30; 
double mySalary=100000; 

object empData = new { name = myName, age = myAge, salary = mySalary }; 

Así que en su escenario se tendría que analizar los elementos individuales de la cadena, y realizar algunas conversiones en ellos para obligarlos a los tipos que quiera.

Si no está casado con este formato de cadena en particular, puede serializar y deserializar sus objetos y lograr lo mismo usando XML mucho más fácilmente.

+0

+1 por pensar fuera de los límites de la pregunta ... debe estarse haciendo tarde – BenAlabaster

Cuestiones relacionadas