Domanda

C'è qualcosa da usare per determinare se un tipo è effettivamente un tipo anonimo? Ad esempio un'interfaccia, ecc.

L'obiettivo è creare qualcosa di simile al seguente ...

//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");

O è solo la bellezza di un tipo anonimo? Niente per identificarlo da solo perché prende una nuova forma?

Nota - Mi rendo conto che puoi scrivere un metodo di estensione per la classe oggetto , ma secondo me sembra un po 'eccessivo.

È stato utile?

Soluzione

EDIT: l'elenco seguente si applica ai tipi anonimi C #. VB.NET ha regole diverse - in particolare, può generare tipi anonimi mutabili (e lo fa di default). Jared ha sottolineato nel commento che anche lo stile di denominazione è diverso. Fondamentalmente questo è abbastanza fragile ...

Non puoi identificarlo in un vincolo generico, ma:

  • Sarà una classe (piuttosto che interfaccia, enum, struct ecc)
  • Avrà CompilerGeneratedAttribute applicato ad esso
  • Sostituirà Equals, GetHashCode e ToString
  • Sarà nello spazio dei nomi globale
  • Non verrà nidificato in un altro tipo
  • Sarà interno
  • Sarà sigillato
  • Deriverà direttamente da object
  • Sarà generico con tanti parametri di tipo quante sono le proprietà. ( puoi avere un tipo anonimo non generico, senza proprietà. Tuttavia è un po 'inutile.)
  • Ogni proprietà avrà un parametro di tipo con un nome incluso il nome della proprietà e sarà di quel parametro di tipo, ad es. la proprietà Name diventa una proprietà di tipo < > _Name
  • Ogni proprietà sarà pubblica e di sola lettura
  • Per ogni proprietà ci sarà un campo privato di sola lettura corrispondente
  • Non ci saranno altre proprietà o campi
  • Ci sarà un costruttore che accetta un parametro corrispondente a ciascun parametro di tipo, nello stesso ordine dei parametri di tipo
  • Ogni metodo e proprietà avrà il DebuggerHiddenAttribute applicato ad esso.
  • Il nome del tipo inizierà con " < > " e contiene " AnonymousType "

Tuttavia, molto poco è garantito dalle specifiche, quindi potrebbe cambiare tutto nella prossima versione del compilatore, o se usi Mono ecc.

Altri suggerimenti

Come ricordo, esiste un [CompilerGenerated] marker ... 2 secondi

Inoltre il nome sarà strano e sarà di tipo generico ;-p

In realtà, per un " get " ecc. Probabilmente userei solo un metodo statico (non di estensione).

Se vuoi solo un modo per ottenere il valore da un'istanza di un tipo anone (in un momento successivo), una lambda è probabilmente l'opzione migliore - nota che hai bisogno di alcuni trucchi per farlo:

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

(modifica il commento) Sicuramente è questo attributo:

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

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

Ai fini dei metodi di estensione non è possibile distinguere un tipo anonimo. I metodi di estensione funzionano specificando un metodo per un tipo identificabile in fase di compilazione. I tipi anonimi non sono nominabili e pertanto non sono visibili al momento della compilazione. Ciò li rende incompatibili con i metodi di estensione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top