Phantom: Easy reflection in .NET. Agora genérico.

Pessoal,

Aqui vai uma dica e um novo método de extensão do Object, para facilitar a nossa vida na hora de recuperar valores de tipos anônimos quando precisamos retorná-los entre métodos.

Há um tempo, o @ajunior84 achou uma biblioteca chamada Phantom, que utilizando reflection, serviu como uma luva para o problema de retornar um tipo anônimo entre métodos. Por padrão, temos intellisense no tipo anônimo apenas no contexto da criação dele.

Na internet, achei uma outra solução, mas essa forma de cast não me agradou muito.

O Phantom foi criado por um brasileiro chamado Wagner Andrade. Sua utilização é muito simples, como ele descreve em seu blog.

Basicamente, para este caso, vamos utilizar um ou dois métodos: Get(propertyName) ou GetString(propertyName). Não precisaremos utilizar os outros métodos de extensão do Phantom para este caso, como o Set(propertyName, value), pois o tipo anônimo é readonly.

Como funciona?

class Program
{
    static void Main(string[] args)
    {
        object obj = RecuperarObjAnonimo();

        string nome = obj.GetString("Nome");
        string ug = obj.GetString("UG");

        Console.WriteLine(nome);
        Console.WriteLine(ug);

        Console.ReadLine();
    }

    private static object RecuperarObjAnonimo()
    {
        return new
        {
            Nome = "Bruno Kenj",
            UG = "BRASILDOTNET",
            Idade = 26
        };
    }
}

Bem simples, não?

Para facilitar mais ainda, resolvi criar um método genérico para retornar o valor tipado. Então, basicamente, vamos chamar o método GetOrDefault(propertyName). Se não conseguir fazer a conversão para o tipo especificado, é retornado o default do tipo.

Vamos ao código do método de extensão:

PhantomExtensions.cs

using System;

namespace Phantom
{
    /// <summary>
    /// Extensão para os métodos Get do Phantom - Recuperar através do nome da propriedade o valor de tipos anônimos.
    /// </summary>
    public static class PhantomExtensions
    {
        public static TResult GetOrDefault<TResult>(this Object obj, string propertyName)
        {
            try { return (TResult)obj.Get(propertyName); }
            catch (Exception) { return default(TResult); }
        }
    }
}

Caso a propriedade não exista, o método lançará uma exceção PhantomException. E por fim, a utilização:

int idade = obj.GetOrDefault<int>("Idade"); // 26
int? idadeNullable = obj.GetOrDefault<Nullable<int>>("Idade"); //26

int idade = obj.GetOrDefault<int>("_Idade"); // 0
int? idadeNullable = obj.GetOrDefault<Nullable<int>>("_Idade"); //null

Caso não exista a propriedade Idade dentro do tipo anônimo ou a conversão não seja válida, é retornado o valor padrão do tipo informado. No caso do int, o valor seria 0. No caso do int?, o valor seria null.

Espero que gostem.

abraços,

3 Responses to “Phantom: Easy reflection in .NET. Agora genérico.”

  1. Boas Bruno,

    Não seria mais simples utilizar dynamic?

  2. Grande Israel!

    Sem dúvida nenhuma. Dynamic é muito bacana! Essa solução foi feita pensando no C# 3.0, hehe. Vou fazer esse exemplo usando o Dynamic do 4.0. Boa dica! abraços…

  3. @Israel

    Adicionei o post com este exemplo utilizando dynamic:

    http://www.brunokenj.net/blog/index.php/2010/05/07/c-4-0-tipos-dinamicos/

    Eu gostei… facilita muito. O que você achou?

    abraços,

Leave a Reply