2009-10-30 16 views

risposta

35

Anche se un tipo anonimo è un tipo ordinario, è possibile utilizzare alcune euristiche:

public static class TypeExtension { 

    public static Boolean IsAnonymousType(this Type type) { 
     Boolean hasCompilerGeneratedAttribute = type.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Count() > 0; 
     Boolean nameContainsAnonymousType = type.FullName.Contains("AnonymousType"); 
     Boolean isAnonymousType = hasCompilerGeneratedAttribute && nameContainsAnonymousType; 

     return isAnonymousType; 
    } 
} 

Un'altra buona euristica da usare è se il nome della classe è un nome valido C# (tipo anonimo vengono generati senza nomi di classi C# validi: usa l'espressione regolare per questo).

+1

+ 1 Bella risposta. –

+0

@Philip ma non infallibile, vedi questa domanda. –

+1

@MattWarren, quale domanda? –

2

In methadata e CLR non c'è termini quali tipi anonimi. I tipi anonimi sono solo funzionalità del compilatore.

1

Potrebbe essere utile sapere perché lo vuoi sapere. Se si esegue il seguente:

var myType = new { Name = "Bill" }; 
Console.Write(myType.GetType().Name ); 

... si dovrebbe vedere qualcosa di simile a "<> f__AnonymousType0`1" uscita come il nome del tipo. A seconda delle tue esigenze, potresti essere in grado di supporre che un tipo che inizia con <>, contenente "AnonymousType" e un carattere di citazione posteriore sia quello che stai cercando.

+0

Non ti preoccupare perché. È curiosità :) – xyz

+0

Ho pensato la stessa cosa, ma è un po 'sporca. Cosa succede se cambiano il nome in C# 5? Qualsiasi codice che lo utilizza sarà rotto. –

+0

È importante chiedere e spiegare "perché" perché spesso ci sono altre possibili risposte che potrebbero non essere evidenti dalla domanda senza saperne di più. –

1

Sembra che i tipi anonimi ottengano un DebuggerDisplayAttribute inserito in corrispondenza di Type = "<Anonymous Type>".

Modifica: ma solo quando si compila in modalità debug. Darn.

+0

Anche in versione build? –

5

Non c'è linguaggio C# costrutto che permette di dire "E 'questo un tipo anonimo". È possibile utilizzare un'euristica semplice per approssimare se un tipo è un tipo anonimo, ma è possibile essere ingannato dall'IL di codifica manuale di persone o utilizzare una lingua in cui tali caratteri come > e < sono validi negli identificatori.

public static class TypeExtensions { 
    public static bool IsAnonymousType(this Type t) { 
    var name = t.Name; 
    if (name.Length < 3) { 
     return false; 
    } 
    return name[0] == '<' 
     && name[1] == '>' 
     && name.IndexOf("AnonymousType", StringComparison.Ordinal) > 0; 
} 
14

proprietà di un oggetto tipizzato anonimo

  • ha uno spazio dei nomi uguale a null
  • tipo di base System.Object
  • IsSealed = true
  • attributo personalizzato 0 è DebuggerDisplayAttribute, Tipo : ""
  • IsPublic = false

Per la mia particolare applicazione, se lo spazio dei nomi è nullo si può dedurre che il tipo è anonimo, in modo da verificare che lo spazio dei nomi è nullo è probabilmente il controllo meno costoso.

+1

Grazie, optando per il tipo di ritorno.NomeSpace == null; migliorato l'elaborazione dei miei programmi di quasi il 50% (stava usando questo approccio: http://stackoverflow.com/questions/2483023/how-to-test-if-a-type-is-anonymous) – Schalk

+0

Sì. Questa dovrebbe essere la risposta corretta. Non credo che qualsiasi classe concreta ragionevole abbia mai uno spazio dei nomi nullo. –

+0

+1 grazie! Lasciando qui il mio commento per favorire questa risposta (non solo una discussione) –

Problemi correlati