How does an anonymous guy get back?

Asked

Viewed 2,603 times

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 him to return a type list List<dynamic> however in this way I received the following build error:

Error CS0029 Cannot implicitly Convert type 'System.Collections.Generic.List<>' to 'System.Collections.Generic.List'

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


Question

I’d like to know how I can returns an anonymous type Anonymoustype by a method?

  • It’s hard to answer that. Is there any pattern in the types that will be returned?

  • Returned types represent a database table.

  • And what is the way you are trying to use the return of this method? I think return a list of object should work.

  • @jbueno the return is the fields q are being selected through a query using Dapper to return a IEnumerable<dynamic> resultado however need to return a typed list to popular a Datagridview through the property DataSource.

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 guarantee that the list is objects. When you receive you will probably have to make a cast for correct type op, then it is better to generate it already so. Unless you want to throw static typing in the trash. Do so:

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;
    }
}

Behold working in the ideone. And in the .NET Fiddle. Also I put on Github for future reference.

You can use it like this, but honestly, it’s better 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) => (T)obj;
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

If you don’t want class, the C# 7 has tuple in the language same, but it’s a beautiful abuse.

  • I researched here a form tbm and it is not possible to return the anonymous types, I will create the same class, otherwise it will become too complex and to stir in the future will be difficult :D

3

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

You may not declare that a field, property, event or return type of a method has an anonymous type. Likewise, no can declare that a formal parameter of a method, property, constructor or indexer has an anonymous type. To pass a type anonymous or a collection that contains anonymous types, such as an argument for a method, you can declare the parameter as type object. No however, this nullifies the purpose of the strong types. If you need store the results of the query or pass them outside the limit of the method, consider using a denomination structure or class ordinary instead of an anonymous type.

https://msdn.microsoft.com/pt-BR/library/bb397696.aspx

What you can do is create a class for your return, 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; }
}
  • I did not deny the answer... In this case I would be returning a class, I would need to return an anonymous type or a list enumerated with the anonymous objects containing the properties. I have several queries if I will have to create a class for each will give me a lot of trouble :(

  • I would particularly prefer to follow this path of creating a class for each return of my queries, but searching a little more I found this possibility http://stackoverflow.com/a/7494146/2221388, but even so you wouldn’t be returning an anonymous type and yes Dynamic

  • 1

    Pablo researched about the return of anonymous types and there is no way to do what I wish. You and Bigown showed me that it is better to create the model class only with the desired fields, even q of more code, and but it seems worth creating the class. + 1 :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.