Devolviendo el tipo anónimo en C #

Tengo una consulta que devuelve un tipo anónimo y la consulta está en un método. ¿Cómo se escribe esto?

public "TheAnonymousType" TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return "TheAnonymousType"; } } 

No puedes.

Solo puede devolver object o contenedores de objetos, por ejemplo, IEnumerable , IList , etc.

Puede devolver la dynamic que le dará una versión comprobada en tiempo de ejecución del tipo anónimo, pero solo en .NET 4+

No puede devolver tipos anónimos. ¿Puedes crear un modelo que pueda devolverse? De lo contrario, debes usar un object .

Aquí hay un artículo escrito por Jon Skeet sobre el tema

Código del artículo:

 using System; static class GrottyHacks { internal static T Cast(object target, T example) { return (T) target; } } class CheesecakeFactory { static object CreateCheesecake() { return new { Fruit="Strawberry", Topping="Chocolate" }; } static void Main() { object weaklyTyped = CreateCheesecake(); var stronglyTyped = GrottyHacks.Cast(weaklyTyped, new { Fruit="", Topping="" }); Console.WriteLine("Cheesecake: {0} ({1})", stronglyTyped.Fruit, stronglyTyped.Topping); } } 

O, aquí hay otro artículo similar

O, como comentan otros, podrías usar dynamic

Puede usar la clase Tuple como sustituto de un tipo anónimo cuando sea necesario volver:

Nota: Tuple puede tener hasta 8 parámetros.

 return Tuple.Create(variable1, variable2); 

O, para el ejemplo de la publicación original:

 public List> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select Tuple.Create(..., ...) ).ToList(); return TheQueryFromDB.ToList(); } } 

http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

El comstackdor de C # es un comstackdor de dos fases. En la primera fase solo verifica espacios de nombres, jerarquías de clases, firmas de métodos, etc. Los cuerpos de los métodos se comstackn solo durante la segunda fase.

Los tipos anónimos no se determinan hasta que se comstack el cuerpo del método.

Entonces el comstackdor no tiene forma de determinar el tipo de retorno del método durante la primera fase.

Esa es la razón por la cual los tipos anónimos no se pueden usar como tipo de devolución.

Como otros han sugerido si está utilizando .net 4.0 o rallador, puede usar Dynamic .

Si yo fuera tú probablemente crearía un tipo y regresaría ese tipo del método. De esta forma, es fácil para los futuros progtwigdores que mantienen su código y son más legibles.

Tres opciones:

Opción 1:

 public class TheRepresentativeType { public ... SomeVariable {get;set;} public ... AnotherVariable {get;set;} } public IEnumerable TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; } } 

Opcion 2:

 public IEnumerable TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; } } 

puedes iterarlo como objeto

Opción 3:

 public IEnumerable TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; //You may need to call .Cast(), but I'm not sure } } 

y podrás iterarlo como un objeto dynamic y acceder a sus propiedades directamente

En C # 7 podemos usar tuplas para lograr esto:

 public List<(int SomeVariable, string AnotherVariable)> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB.Select(s => (SomeVariable = s.SomeVariable, AnotherVariable = s.AnotherVariable)).ToList(); } } 

Sin embargo, es posible que necesites instalar el paquete System.ValueTuple nuget.

Puede devolver la lista de objetos en este caso.

 public List TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB ; } } 
 public List TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new SomeClass{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB.ToList(); } } public class SomeClass{ public string SomeVariable{get;set} public string AnotherVariable{get;set;} } 

Crear tu propia clase y consultarla es la mejor solución que conozco. Por lo que sé, no puedes usar valores anónimos de devolución de tipo en otro método, porque no solo se reconocerá. Sin embargo, se pueden usar de la misma manera. método. Solía ​​devolverlos como IEnumerable o IQueryable , aunque todavía no permite ver qué hay dentro de la variable de tipo anónimo.

Me encontré con algo así antes cuando estaba tratando de refactorizar algún código, puede consultarlo aquí: Refactorización y creación de métodos separados

Solo puedes usar palabras clave dinámicas

  dynamic obj = GetAnonymousType(); Console.WriteLine(obj.Name); Console.WriteLine(obj.LastName); Console.WriteLine(obj.Age); public static dynamic GetAnonymousType() { return new { Name = "John", LastName = "Smith", Age=42}; } 

Pero con la palabra clave de tipo dynamic, perderá seguridad en tiempo de comstackción, IDE IntelliSense, etc.