¿Hay alguna manera de devolver el tipo anónimo del método?

Sé que no puedo escribir un método como:

public var MyMethod() { return new{ Property1 = "test", Property2="test"}; } 

Puedo hacerlo de otra manera:

 public object MyMethod() { return new{ Property1 = "test", Property2="test"} } 

pero no quiero hacer la segunda opción porque, si lo hago, tendré que usar la reflexión.


Por qué quiero hacer eso:

Hoy tengo un método dentro de mi página aspx que devuelve una tabla de datos como resultado y no puedo cambiarla , estaba tratando de convertir esta DataTable a un método anónimo con las propiedades con las que quiero trabajar. No quería crear una clase solo para hacer eso y como tendré que realizar la misma consulta más de una vez, pensé que crear un método que devuelva un tipo anónimo sería una buena idea.

Devolverlo como un System.Object es la única manera de devolver un tipo anónimo desde un método. Lamentablemente, no hay otra forma de hacerlo, ya que los tipos anónimos se diseñaron específicamente para evitar su uso de esta manera.

Hay algunos trucos que puede hacer junto con la devolución de un Object que le permite acercarse. Si está interesado en esta solución alternativa, lea ¿No puede devolver el tipo anónimo del método? De Verdad? .

Descargo de responsabilidad: a pesar de que el artículo que he vinculado muestra una solución que no significa que sea una buena idea hacerlo. Te recomendaría encarecidamente que no uses este enfoque cuando crear un tipo regular sería más seguro y fácil de entender.

Alternativamente, puede usar la clase Tuple en .NET 4.0 y superior:

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

 Tuple Create() { return Tuple.Create("test1", "test2"); } 

entonces puedes acceder a propiedades como esta:

 var result = Create(); result.Item1; result.Item2; 
 public object MyMethod() { return new { Property1 = "test", Property2 = "test" }; } static void Main(..) { dynamic o = MyMethod(); var p1 = o.Property1; var p2 = o.Property2; } 

La solución más fácil es crear una clase, introducir los valores en la propiedad y luego devolverlos. Si los tipos anónimos te están haciendo la vida más difícil, entonces no los estás usando correctamente.

A pesar de las advertencias sobre si esta es una buena idea o no … Una dynamic parece funcionar bien para un método privado.

 void Main() { var result = MyMethod(); Console.WriteLine($"Result: {result.Property1}, {result.Property2}"); } public dynamic MyMethod() { return new { Property1 = "test1", Property2 = "test2" }; } 

Puede ejecutar este ejemplo en LinqPad. Saldrá:

Resultado: test1, test2

Como alternativa, comenzando con C # 7 podemos usar ValueTuple . Un pequeño ejemplo de aquí :

 public (int sum, int count) DoStuff(IEnumerable values) { var res = (sum: 0, count: 0); foreach (var value in values) { res.sum += value; res.count++; } return res; } 

Y en el extremo receptor:

 var result = DoStuff(Enumerable.Range(0, 10)); Console.WriteLine($"Sum: {result.Sum}, Count: {result.Count}"); 

O:

 var (sum, count) = DoStuff(Enumerable.Range(0, 10)); Console.WriteLine($"Sum: {sum}, Count: {count}"); 

Creo que Andrew Hare tiene razón, solo tendrías que devolver “objeto”. Para un comentario editorial, siento que tratar con objetos en código OO puede ser un “olor a código”. Hay casos en los que es lo correcto, pero la mayoría de las veces será mejor que defina una interfaz para regresar, o utilice algún tipo de clase base, si va a devolver tipos relacionados.

No, los tipos anónimos no pueden existir fuera del contexto en el que se crean y, como resultado, no se pueden usar como un tipo de devolución de método. Puede devolver la instancia como un object , pero es una idea mucho mejor crear explícitamente su propio tipo de contenedor para este propósito.

Lo siento, realmente no deberías hacer eso. Puede recorrerlo con reflexión o haciendo un método de ayuda genérico para devolverle el tipo, pero hacerlo realmente funciona en contra del lenguaje. Simplemente declare el tipo para que quede claro lo que está pasando.

No, no hay soporte para expandir el scope de la clase anónima fuera del método. Fuera del método, la clase es verdaderamente anónima, y ​​la reflexión es la única forma de acceder a sus miembros.

También puede invertir su flujo de control si es posible:

  public abstract class SafeAnon { public static Anon Create(Func anonFactory) { return new Anon(anonFactory()); } public abstract void Fire(TContext context); public class Anon : SafeAnon { private readonly T _out; public delegate void Delayed(TContext context, T anon); public Anon(T @out) { _out = @out; } public event Delayed UseMe; public override void Fire(TContext context) { UseMe?.Invoke(context, _out); } } } public static SafeAnon Test() { var sa = SafeAnon.Create(() => new { AnonStuff = "asdf123" }); sa.UseMe += (ctx, anon) => { ctx.Stuff.Add(anon.AnonStuff); }; return sa; } public class SomeContext { public List Stuff = new List(); } 

y luego más adelante en otro lugar:

  static void Main() { var anonWithoutContext = Test(); var nowTheresMyContext = new SomeContext(); anonWithoutContext.Fire(nowTheresMyContext); Console.WriteLine(nowTheresMyContext.Stuff[0]); }