2015-09-21 5 views
17

Quando si utilizza Assembly.GetTypes() Ottengo tipi che hanno Type.Name che iniziano con <>c.....Assembly.GetTypes() restituisce nomi di tipi strani, ad es. "<> c"

Ho provato a google se si tratta di tipi anonimi o qualcos'altro. Ma non riesco a ottenere una risposta davvero buona.

Esiste una proprietà su Tipo che indica quali sono questi tipi? Non mi piace dover fare if(type.Name.StartsWith("<>"))

+2

questi tipi sono generici –

+13

@EhsanSajjad I tipi che hanno un '<> c' non sono generici, sono classi generate dal compilatore. –

+3

Puoi trovare una spiegazione di alcune convenzioni di denominazione dei tipi generate dal compilatore qui: http://stackoverflow.com/a/2509524/55847 – LukeH

risposta

27

Queste sono classi di visualizzazione generate dal compilatore. Si possono distinguere, cercando per il CompilerGeneratedAttribute:

var attr = Attribute.GetCustomAttribute(type, typeof(CompilerGeneratedAttribute)); 
2

Questi sono i CompilerGeneratedAttribute Class

distingue un elemento generato dal compilatore da un elemento generati dagli utenti. Questa classe non può essere ereditata.

Si può controllare come

using System.Runtime.CompilerServices; 


bool CompilerGen(Type t) 
{ 
    var attr = Attribute.GetCustomAttribute(t, typeof(CompilerGeneratedAttribute)); 
    return attr != null; 
} 
7

Sono tipi compilatore ha generato, che includerebbe tipi anonimi, ma anche le implementazioni di IEnumerable<T>, IEnumerator<T>, IEnumerable e IEnumerator che sono prodotte da yield e la strutture a macchina di stato prodotte da await.

Avranno il CompilerGeneratedAttribute.

Descrivi i nomi come "strani" e sono volutamente tali. Sono tutti nomi che sono nomi .NET validi, ma non validi nei comuni linguaggi .NET, in particolare C# e VB.NET. Ciò significa che non è possibile creare una classe di questo tipo con la codifica C# direttamente, quindi non è necessario avere alcuna logica per verificare che il programmatore non abbia creato una classe corrispondente.

+1

E lambda (soprattutto chiusure). Anche ciò che è stato compilato in un delegato statico in C# 5 è ora una variabile di istanza singleton di una classe denominata '<> c' in Roslyn (per motivi di prestazioni in quanto i delegati legati all'istanza sono più veloci da chiamare nella CLI). –

+0

Cosa accadrebbe se qualcuno dichiarasse un'altra classe con lo stesso nome? Il compilatore avrebbe trovato un altro nome? – IllusiveBrian

+0

@Namfuak come? Come ho detto, i nomi vengono scelti deliberatamente come nomi che sono nomi .NET validi ma nomi C# non validi. Non puoi chiamare una classe C# qualcosa che inizia con '<'. –

Problemi correlati