2010-02-19 15 views
6

Tengo un Dictionary(TKey, TValue) comotipos anónimos

Dictionary<int, ArrayList> Deduction_Employees = 
    new Dictionary<int, ArrayList>(); 

y luego agrego a la lista de arreglo un tipo anónimo como esto

var day_and_type = new { 
    TheDay = myDay, 
    EntranceOrExit = isEntranceDelay 
}; 

Deduction_Employees[Employee_ID].Add(day_and_type); 

Ahora, ¿cómo puedo unboxing que var y accede a esas propiedades ??

+4

La gran pregunta es ¿por qué quieres? ¿Qué estás intentando lograr? – pdr

Respuesta

13

Primero, no está desempaquetando el tipo. Los tipos anónimos son tipos de referencia, no estructuras.

A pesar de que técnicamente puede crear instancias del mismo tipo fuera del método que se declaran en (según la sección 7.5.10.6 de la C# 3.0 Especificación del lenguaje, que establece:

Dentro del mismo programa , dos inicializadores de objeto anónimos que especifican una secuencia de propiedades de los mismos nombres y tiempo de compilación tipos en el mismo orden producirá casos de el mismo tipo anónimo.

) no tiene forma de obtener el nombre del tipo que necesita para realizar el molde desde Object al tipo que ha creado. Tendría que recurrir a un cast-by-example solution que es intrínsecamente defectuoso.

Cast-por ejemplo es defectuoso porque desde el punto de vista del diseño, cada lugar al que desee acceder al tipo fuera de la función está declarado (y aún dentro del mismo módulo), debe declarar el tipo de manera efectiva de nuevo.

Es una duplicación de esfuerzo que conduce a un diseño descuidado e implementación.

Si está utilizando .NET 4.0, entonces podría colocar la instancia del objeto en una variable dinámica. Sin embargo, la principal desventaja es la falta de verificación en tiempo de compilación del acceso de los miembros. Puede escribir mal el nombre del miembro y luego tiene un error en tiempo de ejecución en lugar de un error en tiempo de compilación.

En última instancia, si encuentra la necesidad de utilizar un tipo anónimo fuera del método en el que está declarado, la única buena solución es crear un tipo concreto y sustituir el tipo anónimo por el tipo anónimo.

1

No, no puedes. Solo puede acceder a las propiedades mediante el uso de la reflexión. El compilador no tiene forma de saber de qué tipo era, y dado que es un tipo anónimo, tampoco puedes formatearlo.

1

Si está utilizando .NET 1.x - 3.x, debe usar la reflexión.

Si usa .NET 4.0, puede usar un tipo dinámico y llamar a las propiedades esperadas.

En ninguno de los casos es necesario desempaquetar; eso es para tipos de valores. Los tipos anónimos son siempre tipos de referencia.

3

Un tipo anónimo tiene un alcance de método. Para pasar un tipo anónimo, o una colección que contiene tipos anónimos, fuera de un límite de método, primero debe enviar el tipo al objeto. Sin embargo, esto frustra la tipificación fuerte del tipo anónimo. Si debe almacenar los resultados de su consulta o pasarlos fuera del límite del método, considere el uso de una estructura o clase denominada ordinaria en lugar de un tipo anónimo.

Fuente: http://msdn.microsoft.com/en-us/library/bb397696.aspx

8

Hay varias maneras.

Dado que los comentarios parecen indicar que le sugiero que haga esto, permítame dejarlo en claro: Debe crear un tipo con nombre para su objeto, ya que tiene la intención de pasarlo.

Primero, puede usar Reflection, que ya ha señalado otra respuesta aquí.

Otra forma, que engaña .NET en darle el tipo correcto se conoce como "emitir con el ejemplo", y es algo como esto: debe pasar su objeto a través de una llamada al método genérico, que devolverá el objeto como el tipo correcto, al inferir el tipo correcto para regresar.

Por ejemplo, intente esto:

private static T CastByExample<T>(T example, object value) 
{ 
    return (T)value; 
} 

y utilizarlo:

var x = CastByExample(new { TheDay = ??, EntranceOrExit = ?? }, obj); 

para los dos ?? puntos, solo necesita pasar algo que se ajuste al tipo de datos para esas propiedades, los valores no se usarán.

Esto explota el hecho de que múltiples tipos anónimos que contienen exactamente las mismas propiedades, del mismo tipo, en el mismo orden, en el mismo conjunto, se asignarán al mismo tipo individual.

Sin embargo, en este momento debería crear un tipo con nombre en su lugar.

+0

+1 Acabo de ver ese comentario en msdn y cómo explotarlo: "Si dos o más tipos anónimos tienen el mismo número y tipo de propiedades en el mismo orden, el compilador los trata como del mismo tipo y comparten el mismo compilador información de tipo generada ". – Kobi

+0

@Lasse V. Karlsen: En última instancia, cast-por-ejemplo es una parodia. Está efectivamente volviendo a declarar el tipo en cada lugar fuera del método en el módulo al que desea acceder, violando los principios básicos de reutilización. – casperOne

+0

Muy bonito, pero se siente muy incómodo. Casi mal :) –

Cuestiones relacionadas