2009-04-03 24 views
11

¿Cómo accedo a objetos de tipo anónimo fuera del alcance donde está declarado?Accediendo a C# Objetos de tipo anónimo

por ej.

void FuncB() 
{ 
var obj = FuncA(); 
Console.WriteLine(obj.Name); 
} 

??? FuncA() 
{ 
var a = (from e in DB.Entities 
where e.Id == 1 
select new {Id = e.Id, Name = e.Name}).FirstOrDefault(); 

return a; 
} 

Respuesta

26

Como han dicho las otras respuestas, realmente no debería hacer esto. Pero, si insistes, entonces hay un hack desagradable conocido como "lanzar con el ejemplo" que te permitirá hacerlo. La técnica se menciona en un par de artículos, here y here.

public void FuncB() 
{ 
    var example = new { Id = 0, Name = string.Empty }; 

    var obj = CastByExample(FuncA(), example); 
    Console.WriteLine(obj.Name); 
} 

private object FuncA() 
{ 
    var a = from e in DB.Entities 
      where e.Id == 1 
      select new { Id = e.Id, Name = e.Name }; 

    return a.FirstOrDefault(); 
} 

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

(No puedo tomar el crédito por este truco, aunque the author of one of those articles says that he doesn't want to be associated with it either Su nombre podría ser familiar..)

+0

¡Golpeado por 8 segundos! He eliminado el mío (no hay beneficio en duplicarlo). Pero enfatizar :: *** no hagas esto *** ;-p –

+0

Has aceptado esto como tu respuesta preferida. Aunque es una técnica interesante, ¡no recomiendo usarla en ningún código importante/de producción! – LukeH

+1

Ya. Es bueno saber que esto se puede hacer. Sin embargo, es realmente malo, pero yo también. Muhahhhhahahaaaa. –

7

No se puede devolver un tipo anónimo de una función.

Desde el MSDN documentation:

Para pasar un tipo anónimo, o una colección que contiene los tipos anónimos, fuera de un límite método, primero debe convertir el tipo de 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.

1

El tipo anónimo es simplemente una clase generada por el compilador, y el compilador no está dispuesto a decirle el nombre de la clase en sí. Por lo tanto, no hay forma de que pueda devolver una instancia de esta clase desde una función que no sea devolver una referencia a object.

1

Bueno, creo que la respuesta es: No use un tipo anónimo fuera del alcance donde está declarado. En este caso, crea un tipo simple.

0

crearía una clase para este caso:

public class LISTFUNCA 
{       
    public int identificacion; 
    public string nombre;  
}  

a continuación:

public List<LISTFUNCA> FuncA() 
{           
    var lista = (from e in DB.Entities where e.Id == 1       
       select new { identificacion = e.Id, nombre = e.Name}) 
       .FirstOrDefault(); 
    return lista.ToList(); 
}  
+1

Revisa tu código; Lo reformaté, pero creo que no es correcto. Además, lea [faq] para obtener detalles sobre cómo formatear su código correctamente. Y, cuando publica algo, y se ve horrible, no olvide que puede [editar su publicación para solucionarlo]. (Http://stackoverflow.com/posts/2509405/edit) – Will

2

Si está utilizando .NET 4.0, puede usar Tuples para esto, devolverá a Tuple<int, string>. Puede implementar sus propias Tuplas para 2.0/3.5, y en realidad otras personas ya las tienen, por lo que debería poder hacer eso si lo desea.

0

El marco de código abierto Impromptu-Interface le permitirá esquivar el lanzamiento de un objeto anónimo a una interfaz. Tiene la ventaja de ser menos hacky porque funcionará como se espera a través de los límites del ensamblaje. Lo logra usando un proxy liviano y el dlr.

Cuestiones relacionadas