2010-02-19 15 views
15

Para un Type, hay una propiedad IsClass en C#, pero ¿cómo decidir un Type es una estructura?¿Cómo decidir un Tipo es una estructura personalizada?

Aunque IsValueType es una condición necesaria, obviamente no es suficiente. Para un int también es un tipo de valor.

Alguien sugiere el siguiente código:

bool IsStruct = type.IsValueType && !type.IsEnum && !type.IsPrimitive; 

Pero no estoy seguro de si se trata de un método exacto. La fórmula debería indicar la diferencia entre struct y otros tipos, como DateTime, int y array s.

Como algunos amigos han señalado aquí, quiero decir estructura definida por el usuario y tipos no predefinidos, como DateTime.

+2

No estoy seguro de entender la pregunta. Un DateTime ** es ** una estructura. ¿Por qué devolverías falso allí? –

+3

En realidad, int también es un tipo de estructura. La especificación del lenguaje indica que "C# proporciona un conjunto de tipos de estructura predefinidos denominados tipos simples". –

+2

Sería interesante saber por qué te importa. ¿Qué estás haciendo? Puede haber una mejor manera de hacer lo que quieras. –

Respuesta

8

Técnicamente, un int también es una estructura. IsPrimitive solo comprueba si el tipo es uno de los tipos primitivos que CLR maneja de forma un poco diferente. Debería estar bien con la sugerencia IsValueType && !IsEnum && !IsPrimitive.

Si solo desea estructuras personalizadas (es decir, aquellas que no proporciona el BCL), puede tener suerte excluyendo tipos con un nombre completo que empiece por "System.", o solo las que le interesen filtrando por ensamblado o espacio de nombres , o usa un atributo personalizado.

+2

+1 O '" Microsoft. '' O '" FSharp. "' O. . . Creo que tendrá dificultades para eliminarlos a todos. –

2

debería ser al menos

bool isStruct = type.IsValueType && !type.IsEnum && 
       !type.IsPrimitive && type != typeof(decimal); 
0

Vas a tener un tiempo duro con esto. El Framework base no sabe cuáles son todos los tipos predefinidos en otras partes del Framework. No es razonable esperar que el Marco central sepa aproximadamente System.Drawing.Point, por ejemplo.

OregonGhost tiene probablemente el mejor answer: obtenga la información del tipo y revise la propiedad FullName para ver si comienza con "System.". Pero también deberá verificar "Microsoft." y "FSharp", y posiblemente otros. Simplemente haga clic en "Agregar una referencia" en Visual Studio y vea qué nombres aparecen.

Y luego puede arriesgarse a bloquear demasiado. Microsoft distribuye algunos ensamblajes a través de paquetes NuGet, y los tipos en esos ensamblados a menudo tienen nombres que comienzan con "System." o "Microsoft.". ¿Considera esos tipos "integrados" aunque no se distribuyan con el marco?

1

http://msdn.microsoft.com/en-us/library/bfft1t3c.aspx dice: IsValueType es cierto si el tipo está en {bool, byte, char, decimales, doble, enumeración, flotador, int, long, sbyte, resumen, estructura, uint ulong, ushort}.

http://msdn.microsoft.com/en-us/library/system.type.isprimitive%28v=vs.110%29.aspx dice: IsPrimitive es cierto si el tipo está en {Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, doble y simple}.

Que para IsStruct se puede utilizar el método de la siguiente manera:

public static bool IsStruct(this Type type) 
{ 
    return type.IsValueType 
      && !type.IsPrimitive 
      && !type.IsEnum 
      && type != typeof(decimal); 
} 
0

que trabajó para mí x.PropertyType.IsSecurityTransparent & & x!.PropertyType.IsClass

0

No es una solución perfecta, pero siempre se puede tener en cuenta la reducción de la búsqueda por tipos conocidos dentro de los conjuntos que desea buscar:

System.Reflection.Assembly.GetAssembly(tyepof(OneOfMyTypes)) 
    .GetExportedTypes() 
    .Where(t => t.IsValueType); 

La ayuda a eliminar los falsos positivos (? Seguro), pero es menos portátil.

Cuestiones relacionadas