How does an anonymous type return?

5

I have a method that should return a collection of anonymous objects:

/*Aqui deveria ser o tipo anonimo "AnonymousType"*/
[AnonymousType] ListarAnonimo()
{
    //Especifica um "template" para o tipo retornado.
    var lista = new[]
    {
        new
        {
            Nome = "",
            Idade = 0,
            Salario = 0.0m
        }
    }.ToList();

    lista.Clear();

    //Adiciona um item.
    lista.Add(new
    {
        Nome = "Gato",
        Idade = 25,
        Salario = 3000000.0m
    });

    return lista;
}

I tried to get it to return a list of type List<dynamic> but in this way I received the following compilation error:

  

Error CS0029 Can not implicitly convert type   'System.Collections.Generic.List < >' to   'System.Collections.Generic.List'

So I tried to use List<object> but I got the same error.

Question

I'd like to know how I can return an anonymous type AnonymousType through a method?

    
asked by anonymous 11.02.2017 / 22:12

2 answers

6

I do not recommend doing so, it is better to have a class to generate. In fact this example seems fictitious and it is unnecessary not to have a type. If you want to insist, I assure you the list is object s. When you receive it will probably have to cast cast to op right type, so it's better to generate it already so. Unless you want to throw away the static typing. Here's how:

using System.Collections.Generic;
using System.Linq;

public class Program {
    public static void Main() {
        var lista = ListarAnonimo();
    }
        public static List<object> ListarAnonimo() {
        var lista = new object[] {
            new {
                Nome = "",
                Idade = 0,
                Salario = 0.0m
            }
        }.ToList();
        lista.Clear();
        lista.Add(new {
            Nome = "Gato",
            Idade = 25,
            Salario = 3000000.0m
        });
        return lista;
    }
}

See running on .NET Fiddle . And at Coding Ground . Also I put it in GitHub for future reference .

You can use this, but honestly, it's best to create the class:

using static System.Console;
using System.Collections.Generic;
using System.Linq;

public class Program {
    public static void Main() {
        var lista = ListarAnonimo();
        foreach (var item in lista) {
            var pessoa = Util.Cast(item, new { Nome = "", Idade = 0, Salario = 0.0m });
            WriteLine($"Nome: {pessoa.Nome} - Idade: {pessoa.Idade} - Salario {pessoa.Salario}");
        }
    }
    public static List<object> ListarAnonimo() {
        var lista = new object[] {
            new {
                Nome = "",
                Idade = 0,
                Salario = 0.0m
            }
        }.ToList();
        lista.Clear();
        lista.Add(new {
            Nome = "Gato",
            Idade = 25,
            Salario = 3000000.0m
        });
        return lista;
    }
}

public static class Util {
    public static T Cast<T>(object obj, T type) {
        return (T)obj;
    }
}

See running on .NET Fiddle . And at Coding Ground . Also put it on GitHub for future reference .

If you do not want the class itself, C # 7 has tuple in the language , but it is a beautiful abuse .

    
11.02.2017 / 22:50
3

I believe it is not possible for you to return an anonymous type.

  

You can not declare that a field, a property, an event, or a   return type of a method has an anonymous type. In the same   can declare that a formal parameter of a method, property,   constructor or indexer has an anonymous type. To pass a type   anonymous collection, or a collection that contains anonymous types, such as an argument   for a method, you can declare the parameter as object type. At the   However, this negates the purpose of the strong types. If you need   store the results of the query or pass them outside the query   method, consider the use of a structure or class with   common instead of an anonymous type.

link

What you can do is create a class for your return, you can fipublic

List<RetornoModel> ListarAnonimo()
{
    //Especifica um "template" para o tipo retornado.
    var lista = new[]
    {
        new RetornoModel
        {
            Nome = "",
            Idade = 0,
            Salario = 0.0m
        }
    }.ToList();

    lista.Clear();

    //Adiciona um item.
    lista.Add(new RetornoModel()
    {
        Nome = "Gato",
        Idade = 25,
        Salario = 3000000.0m
    });

    return lista;
}

class RetornoModel
{
    public int Idade { get;  set; }
    public string Nome { get; set; }
    public decimal Salario { get; set; }
}
    
11.02.2017 / 22:35