Um tipo anônimo pode ser declarado da seguinte maneira:
var c = new { Nome = "Ari", Idade = 28 };
Neste caso a variável c é um tipo de possui duas propriedades: uma propriedade do tipo System.String chamada Nome e uma propriedade do tipo System.Int32 chamada Idade.
Os tipos anônimos são muito úteis quando realizamos consultas usando o LINQ pois normalmente temos que retornar um tipo com um conjunto de propriedades diferente dos tipos já existentes. Por exemplo, vejam as duas consultas abaixo:
var q1 = from c in dc.Customers where c.City == "London" select new { c.FirstName, c.LastName, c.City }; var q2 = from c in dc.Customers where c.City == "London" select new { c.FirstName, c.City };
A primeira consulta retorna um tipo que contém 3 propriedades (FirstName, LastName e City) e a segunda um tipo com 2 propriedades (FirstName e City). Sem os tipos anônimos teríamos que definir explicitamente duas classes para representar os tipos retornados.
Mas, se o tipo é anônimo, como podemos fazer para um método retorná-lo?
public ???? ListCustomers() { var q1 = from c in dc.Customers where c.City == "London" select new { c.FirstName, c.LastName, c.City }; return q1; }
Bom, podemos resolver essa questão pensando da seguinte maneira: se um tipo anônimo é um tipo do .NET, então esse herda de System.Object, vamos então retornar um object.
public object ListCustomers() { ... }
Esse raciocínio está correto, o problema é que transformando para object perdemos a possibilidade de utilizarmos as propriedades do tipo anônimo diretamente (strong typing).
var c = ListCustomers(); c.FirstName = "Anders"; // erro
Bom, para resolver esse problema temos 3 possíveis soluções:
- Reflection.
- Dynamic Programming.
- Realizar um cast do object com o tipo anônimo.
A primeira opção é lenta e muito código deve ser criado, portanto será descartada. A segunda opção é interessante mas vou limitar meu escopo com as versões anteriores à 4.0. Vou mostrar então a terceira opção.
Para realizarmos um cast de um object para um tipo anônimo podemos, com auxílio de Generics, criar o método abaixo:
public T CastObjectToType<T>(object objeto, T tipo) { return (T)objeto; }
Podemos então converter o objeto em um tipo anônimo da seguinte maneira:
object o = ListCustomers(); var c = CastObjectToType(o, new { FirstName = String.Empty, LastName = String.Empty, City = String.Empty}); c.FirstName = "Anders"; // OK
Isso é possível graças à inferência de tipo, que nos permite fazer um cast sem conhecer o nome do tipo. É o que foi realizado no método CastObjectToType.
Finalizado, a resposta é SIM. Podemos retornar um tipo anônimo de um método.
Links de ajuda:
Anonymous Types (C# Programming Guide)
http://bit.ly/69HYJd
Generic Methods (C# Programming Guide)
http://bit.ly/6wFbas
Getting Started with LINQ in C#
http://bit.ly/4BOIUU

