Pergunta

Existe alguma coisa para uso, para determinar se um tipo é realmente um tipo anônimo? Por exemplo, uma interface, etc?

O objetivo é criar algo como o seguinte ...

//defined like...
public static T Get<T>(this IAnonymous obj, string prop) {
    return (T)obj.GetType().GetProperty(prop).GetValue(obj, null);
}
//...

//And then used like...
var something = new { name = "John", age = 25 };
int age = something.Get<int>("age");

Ou isso é só a beleza de um tipo anônimo? Nada para identificá-lo auto porque é preciso uma nova forma?

Nota -. Eu percebo que você pode escrever um método de extensão para o objeto classe, mas que parece ser um pouco de exagero, na minha opinião

Foi útil?

Solução

EDIT: A lista abaixo se aplica aos tipos C # anónimos. VB.NET tem regras diferentes - em particular, pode gerar tipos anônimos mutáveis ??(e faz por padrão). Jared apontou no comentário de que o estilo de nomenclatura é diferente, também. Basicamente, isto é tudo muito frágil ...

Você não pode identificá-lo em uma restrição genérica, mas:

  • Será uma classe (em vez de interface, enum, struct etc)
  • Ela terá a CompilerGeneratedAttribute aplicada a ele
  • Vai substituir Equals, GetHashCode e ToString
  • Será no espaço global
  • Não vai ser aninhado em outro tipo
  • Será interna
  • Será selada
  • Será decorrem directamente da object
  • Será genérico com o maior número de parâmetros de tipo como propriedades. (Você pode tem um tipo anônimo não-genérico, sem propriedades. É um inútil pouco embora.)
  • Cada propriedade terá um parâmetro de tipo com um nome, incluindo o nome da propriedade, e será desse tipo de parâmetro, por exemplo, a propriedade Name torna-se uma propriedade do tipo <> _ Nome
  • Cada propriedade será público e somente leitura
  • Para cada propriedade, haverá um campo readonly privada correspondente
  • Não haverá outras propriedades ou campos
  • Haverá um construtor tomar um parâmetro correspondente a cada tipo de parâmetro, na mesma ordem em que os parâmetros de tipo
  • Cada método e propriedade terá a DebuggerHiddenAttribute aplicada a ele.
  • O nome do tipo vai começar com "<>" e contêm "AnonymousType"

Muito pouco deste é garantido pela especificação, no entanto -. Por isso tudo pode mudar na próxima versão do compilador, ou se você usar Mono etc

Outras dicas

Se bem me lembro, há um [CompilerGenerated] marcador ... 2 segundos

Além disso, o nome será estranho, e vai ser um tipo genérico ;-p

Na verdade, por um "ficar" etc eu provavelmente só usar um método estático (não-extensão).

Se você quer apenas uma maneira de obter o valor de uma instância de um tipo Anon (em um ponto posterior no tempo), um lambda é provavelmente a melhor opção - nota você precisa de alguns truques para conseguir isso:

    static void Main()
    {
        var foo = new { name = "John", age = 25 };
        var func = Get(foo, x => x.age);
        var bar = new { name = "Marc", age = 30 };
        int age = func(bar);
    }
    // template here is just for type inference...
    static Func<TSource, TValue> Get<TSource, TValue>(
        TSource template, Func<TSource, TValue> lambda)
    {
        return lambda;
    }

(edit re comentário) Há definitivamente é este atributo:

        var foo = new { A = "B" };
        Type type = foo.GetType();

        CompilerGeneratedAttribute attrib = (CompilerGeneratedAttribute) Attribute.GetCustomAttribute(
            type, typeof(CompilerGeneratedAttribute)); // non-null, therefore is compiler-generated

Para efeitos de métodos de extensão não há nenhuma maneira de distinguir um tipo anônimo. Os métodos de extensão trabalhar especificando um método para um tipo nameable tempo de compilação. Tipos anônimos são un-namable e, portanto, não visível em tempo de compilação. Isso os torna incompatível com os métodos de extensão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top