2010-03-19 13 views
7

Tengo 2 objetos, los cuales quiero convertir a dictionarys. Yo uso toDictionary <>().Lambda "if"?

La expresión lambda de un objeto para obtener la clave es (i => i.name). Para el otro, es (i => i.inner.name). En el segundo, i.name no existe. i.inner.name SIEMPRE existe si i.name no lo hace.

¿Hay una expresión lambda que pueda usar para combinar estos dos? Básicamente para leer como:

"si existe i.name entonces establezca id en i.nombre, sino establezca id en i.inner.name".

Muchas gracias.

actualización

Cuando digo "no existen", me refiero a los objetos en realidad no tienen las propiedades, no es que las propiedades son simplemente nula.

+1

Si dice que las propiedades no existen, ¿quiere decir que los objetos en realidad no tienen las propiedades o que las propiedades son simplemente nulas? – OregonGhost

+0

Los objetos en realidad no tienen las propiedades. – AndrewC

+0

¿Entonces estos dos tipos son dos tipos completamente no relacionados entonces? – shf301

Respuesta

4

¿Por qué no le das a cada objeto un método de su propia ToDictionary, como obviamente tienen sus propios comportamientos en este caso.

Si no puede agregar objetos, porque no los posee, siempre puede escribir métodos de extensión para ellos.

¿Alguna razón por la que trata de forzarlos a alimentarlos en una función "común"?

+0

Tal vez la anulación de ToString() sería la mejor opción de comportamiento para estos objetos. Por supuesto, eso depende de si dependes de otro comportamiento en ToString() en otro lugar ... – ZombieSheep

+0

@Sekhat Solo estaba viendo si podía combinarlo en una función, ya que necesito hacerlo bastantes veces. Por el bien de la limpieza. – AndrewC

2

Sí, el operador condicional ("operador ternario") hace lo que quiere:

(i => i.name != null ? i.name : i.inner.name) 

Suponiendo, claro, que se puede detectar la "existencia" del nombre mediante la comprobación de null.

Editar: En ese caso, la respuesta de Kirschstein es mejor, por supuesto.

+0

Lo que quise decir es que i.name no existe en absoluto. El nombre de la propiedad no está allí. No puedo usar null. Disculpas si no lo entendí bien. – AndrewC

0

algo en la línea de

collection1.ForEach(i => myDictionary.Add((i.name.length == 0 ? i.inner.name : i.name),value); 

(no probado) debe hacer el truco si i.name no es nulo (una cadena vacía), o

collection1.ForEach(i => myDictionary.Add((i.name ?? i.inner.name),value); 

(también probado)

11

Si se trata de dos tipos distintos (de referencia), puede probarlos utilizando las palabras clave is o as:

i => { 
     var x = i as TypeThatHasNameProperty; 
     return (x != null) ? x.name : i.inner.name; 
    } 

Si no puede probar para tipos específicos a continuación, puede utilizar la reflexión para la prueba de la propiedad en sí name:

i => { 
     var pi = i.GetType().GetProperty("name"); 
     return (pi != null) ? pi.GetValue(i, null) : i.inner.name; 
    } 
+2

¿No necesita convertir 'i' en' TypeThatHasNameProperty' antes de poder acceder a la propiedad 'Name'? – dtb

+1

@dtb: Probablemente, supongo que depende de cómo se vea el resto del código OP. (Pero no haría ningún daño hacer el reparto de todos modos, aunque en mi código de ejemplo creo que usar 'como' es probablemente más apropiado que un molde simple.) – LukeH

+0

buen trabajo en esta respuesta –