2010-04-26 19 views
6

Come scrivere un metodo semplice, che controlla se un tipo concreto è una struttura personalizzata (creata con public struct { };) o meno.Come determinare se un tipo .NET è una struttura personalizzata?

Controllo Type.IsValueType non è sufficiente, perché è anche vero per int, long, ecc, e l'aggiunta di un controllo per !IsPrimitiveType non escluderà decimal, DateTime e forse alcuni altri tipi di valore. So che la maggior parte del costruito in tipi di valore sono in realtà "le strutture", ma voglio solo verificare la presenza di "struct custom"

Queste domande sono per lo più lo stesso, ma senza la risposta che ho bisogno:

EDIT: dalle risposte menzionato il "check per il prefisso 'sistema'" è stato il più stabile (anche se è ancora un hack). Alla fine ho deciso di creare un attributo con cui devi decorare la struttura, in modo che il framework lo riprenda come una struttura personalizzata. (L'altra scelta ho pensato è stato quello di creare un'interfaccia vuota, e lasciare che lo struct implementare tale interfaccia vuoto, ma il modo in cui attributo sembrava più elegante)

Qui è la mia originale checker struct personalizzato se qualcuno se interessati:

type.IsValueType && !type.IsPrimitive && !type.Namespace.StartsWith("System") && !type.IsEnum 
+1

Solo per curiosità, perché vuoi rilevarlo? – Joren

+0

Fluent NHibernate + Auto Mapping: imposta tutte le strutture personalizzate da gestire come Componenti (oggetti valore); impostando qualsiasi altro tipo di valore come componente (come DateTime o decimale) si romperà l'intero framework (almeno lo fa in mono) – SztupY

+0

Aggiungi su! type.IsEnum –

risposta

5

Bene, DateTime, decimal, ecc. Soddisfano le vostre esigenze. Per quanto riguarda il CLR, sono strutture personalizzate. Un trucco, ma puoi semplicemente controllare se lo spazio dei nomi inizia con "Sistema".

+0

Ovviamente il tuo spazio dei nomi potrebbe iniziare con System ...:) Nessuno lo farebbe, giusto? –

+2

Sì, è per questo che l'ho chiamato un hack. –

+0

@MattGreer: ottimo strumento a proposito, non potevo pensare a questo :) grazie –

8

Non esiste alcuna differenza tra una struttura definita nel framework e una struttura definita dall'utente.

Un paio di idee potrebbe essere:

  • Tenere una whitelist di struct quadro ed escludere quelli;
  • Identificare l'assembly (DLL) in cui è definito il tipo e mantenere una lista bianca di assembly framework.
  • Identificare lo spazio dei nomi in cui si trova il tipo ed escludere quelli del framework.
+0

Nel contesto del commento sull'utilizzo di Fluent NHibernate, una lista bianca di strutture "ben note" sarebbe l'approccio migliore. L'elenco è abbastanza breve da essere facilmente compreso e probabilmente non cambierà mai. –

+0

D'accordo, quando trovi tutti quelli che causano un arresto anomalo, aggiungili alla lista bianca (o alla lista nera o in qualsiasi modo tu lo chiami), e continua. Il framework non ha troppe strutture. – stusmith

+0

Sì, ma sfortunatamente non ci sono liste per questo. E se perdi qualcosa e usi quella struttura in un secondo momento, non saprai perché i framework iniziano a bloccarsi – SztupY

2

È possibile verificare se il tipo di struttura si trova in qualsiasi punto all'interno dello spazio nomi . Ma ancora una volta non è una soluzione affidabile.

3

mettendo le osservazioni di cui sopra in un metodo extention:

public static class ReflectionExtensions { 
     public static bool IsCustomValueType(this Type type) {    
       return type.IsValueType && !type.IsPrimitive && type.Namespace != null && !type.Namespace.StartsWith("System."); 
     } 
    } 

dovrebbe funzionare

-1

Hai un valore che va con quel tipo? Chiama il metodo ToString e controlla se la stringa restituita inizia con "{".

Se non si dispone di un valore, controllare se ha un costruttore senza parametri. Se non lo fa, è un costruttore. In tal caso, utilizzare Activator per creare un'istanza e chiamare di nuovo il metodo ToString.

Problemi correlati