2010-04-26 11 views
6

Cómo escribir un método simple, que comprueba si un tipo concreto es una estructura personalizada (creada con public struct { };) o no.¿Cómo determinar si un tipo .NET es una estructura personalizada?

Comprobación Type.IsValueType no es suficiente, ya que también es cierto que int, long, etc, y la adición de un cheque a !IsPrimitiveType no excluirá decimal, DateTime y tal vez algunos otros tipos de valores. Sé que la mayoría de los incorporados en los tipos de valor son en realidad "estructuras", pero yo sólo quiero comprobar si hay "estructuras personalizados"

Estas preguntas son en su mayoría el mismo pero sin la respuesta que necesito:

EDIT: de las respuestas se menciona la "comprobar si el prefijo 'System'" fue la más estable (aunque sigue siendo un truco). Finalmente decidí crear un atributo con el que se debe decorar la estructura, para que el marco lo recoja como una estructura personalizada. (La otra opción que pensaba era crear una interfaz vacía, y dejar que la estructura implementar la interfaz vacía, pero la forma atributo parecía más elegante)

Aquí es mi corrector original de estructura personalizada si alguien si está interesado:

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

Solo por curiosidad, ¿por qué quieres detectar esto? – Joren

+0

Fluidez NHibernate + Auto Mapping: configura todas las estructuras personalizadas para manejarlas como componentes (objetos de valor); configurar cualquier otro tipo de valor para que sea un componente (como DateTime o decimal) bloqueará todo el framework (al menos bajo mono) – SztupY

+0

Add on! type.IsEnum –

Respuesta

5

Bien, DateTime, decimal, etc. cumplen sus requisitos. En lo que respecta al CLR, son estructuras personalizadas. Un truco, pero puede verificar si el espacio de nombres comienza con "Sistema".

+0

Por supuesto, su propio espacio de nombre podría comenzar con System ...:) Nadie haría eso, ¿verdad? –

+2

Sí, por eso llamé a eso un truco. –

+0

@MattGreer: gran truco por cierto, no podía pensar en eso :) gracias –

8

No hay diferencia entre una estructura definida en el marco y una estructura definida por usted mismo.

Un par de ideas podría ser:

  • Mantener una lista blanca de estructuras marco, y excluir a aquellos;
  • Identifique el ensamblado (DLL) en el que se define el tipo y conserve una lista blanca de ensamblados de marcos.
  • Identifique el espacio de nombres en el que vive el tipo, y excluya los marcos.
+0

En el contexto del comentario sobre el uso de Fluent NHibernate, una lista blanca de "conocidas" estructuras sería el mejor enfoque. La lista es lo suficientemente corta para que se entienda fácilmente y es probable que nunca cambie. –

+0

De acuerdo, cuando encuentre a cada uno que causa un bloqueo, agréguelo a la lista blanca (o lista negra o como se llame) y continúe. El marco no tiene demasiadas estructuras. – stusmith

+0

Sí, pero desafortunadamente no hay listas para esto. Y si te pierdes algo y usas esa estructura más tarde, no sabrás por qué los frameworks comienzan a fallar – SztupY

2

Puede verificar si el tipo de estructura se encuentra dentro de Espacio de nombres del sistema. Pero nuevamente esa no es una solución confiable.

3

poner los comentarios anteriores en un método de extensión:

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

debería funcionar

-1

¿Tiene un valor que va con ese tipo? Llame al método ToString y compruebe si la cadena devuelta comienza con "{".

Si no tiene un valor, verifique si tiene un constructor sin parámetros. Si no es así, es un constructor. Si lo hace, use Activator para crear una instancia y llame de nuevo al método ToString.

Cuestiones relacionadas