2011-10-04 25 views
5

Duplicar posible:
Is it possible to declare an anonymous type in C# with a variable/dynamic set of fields?¿Cómo agregar propiedades al objeto anónimo dinámicamente?

he construido un generador de consultas que construye una consulta mediante el examen de algunos valores GET que el usuario ha fijado en mi aplicación ASP.NET MVC3. Este generador de consultas puede agregar ordenación, limitación y filtrado (la cláusula WHERE) y luego devuelve la consulta construida.

Esta consulta luego va a mi repositorio apuesto que trata de ejecutar la consulta con:

using (IDbConnection connection = new MySqlConnection(ConnectionStringFactory.GetConnectionString(Database.Push))) 
{ 
    connection.Open(); 

    return connection.Query<Notification>(query.QueryString, 
              new 
              { 
               someAnonymousStuffHere = SomeValue 
              }); 
} 

Sin embargo, los parámetros de la consulta (que es una declaración preparada) necesita ser puesto en un tipo anónimo. El problema es: no sé cómo construir este tipo anónimo de forma dinámica. Lo que hago ahora es presionar todos los parámetros en un diccionario en el generador de consultas, donde la clave es el nombre de la propiedad y el valor es, bueno, el valor.

No puedo simplemente definir un tipo anónimo en mi generador de consultas porque el constructor consta de varios pasos, algunos de los cuales no se ejecutan. Así que a veces tenemos 5 parámetros, a veces tenemos 3 parámetros, etc.

Espero haber explicado mi problema lo suficientemente claro. No dude en solicitar más información :) ¡Gracias de antemano!

+0

¿Qué piensas hacer con este tipo anónimo cuyos miembros no conoces en tiempo de compilación? – Gabe

+0

El tipo anónimo va al método de consulta, que probablemente correlacionará los parámetros con el marcador de posición correcto en la consulta. –

+0

http://stackoverflow.com/questions/7437043/is-it-possible-to-declare-an-anonymous-type-in-c-with-a-variable-dynamic-set-of debería tener su respuesta –

Respuesta

2

Los tipos anónimos todavía se escriben estáticamente en tiempo de compilación. Sugeriría mirar en las características del lenguaje dynamic, o seguir con su diccionario.

Aquí hay un ejemplo de cargar un objeto dinámico desde un diccionario de clave/valores, y luego acceder a él como si fuera un objeto estáticamente estátizado.

//linqpad 
void Main() 
{ 
    IDictionary<string,object> items = new Dictionary<string,object>(); 
    items.Add("test","123"); 

    dynamic props = DynamicProperties.LoadFromDictionary(items); 

    string item = props.test; 

    item.Dump(); 
} 


public class DynamicProperties : DynamicObject 
{ 
    private DynamicProperties(){} 

    private Dictionary<string, object> dictionary = new Dictionary<string, object>(); 

    public static DynamicProperties LoadFromDictionary(IDictionary<string,object> Dictionary) 
    { 
     dynamic dprop = new DynamicProperties(); 
     foreach(var item in Dictionary) 
     { 
      dprop.dictionary.Add(item.Key.ToLower(),item.Value); 
     } 
     return dprop; 
    } 
    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    { 
     string name = binder.Name.ToLower(); 
     Console.WriteLine("Trying to get " + name); 
     return this.dictionary.TryGetValue(name,out result); 
    } 
    public override bool TrySetMember(SetMemberBinder binder, object value) 
    { 
     Console.WriteLine("TrySetMember: " + value.ToString()); 
     this.dictionary[binder.Name.ToLower()] = value; 
     return true; 
    } 
} 
10

Los tipos anónimos son simplemente una conveniencia donde el compilador puede crear un tipo para usted "sobre la marcha" para ahorrar algo de tipeo. Sin embargo, todavía está tipado estáticamente. Si necesita un tipo "más inteligente" con más funcionalidades que las que obtiene de un tipo anónimo o si necesita pasar instancias de ese tipo, debe crear un tipo "real" como lo haría antes de que existieran los tipos anónimos.

Otra opción es utilizar la función dynamic. Puede crear un tipo dinámico utilizando, por ejemplo, ExpandoObject. He aquí un pequeño ejemplo de cómo se puede utilizar:

dynamic expando = new ExpandoObject(); 
expando.Name = "Martin"; 
if (((IDictionary<String, Object>) expando).ContainsKey("Name")) 
    Console.WriteLine(expando.Name); 

El expando es realmente un diccionario glorificado y el uso de un diccionario en su lugar (como lo hace) podría llegar a ser una mejor opción.

Cuestiones relacionadas