c# reflection primitive-types

c# - Cómo probar si el tipo es primitivo



reflection primitive-types (12)

Acabo de encontrar esta pregunta mientras buscaba una solución similar, y pensé que podría estar interesado en el siguiente enfoque utilizando System.TypeCode y System.Convert .

Es fácil serializar cualquier tipo que esté mapeado en un System.TypeCode no sea System.TypeCode.Object , por lo que podría hacer:

object PropertyValue = ... if(Convert.GetTypeCode(PropertyValue) != TypeCode.Object) { string StringValue = Convert.ToString(PropertyValue); ... }

La ventaja de este enfoque es que no tiene que nombrar cualquier otro tipo no primitivo aceptable. También puede modificar ligeramente el código anterior para manejar cualquier tipo que implemente IConvertible.

Tengo un bloque de código que serializa un tipo en una etiqueta Html.

Type t = typeof(T); // I pass <T> in as a paramter, where myObj is of type T tagBuilder.Attributes.Add("class", t.Name); foreach (PropertyInfo prop in t.GetProperties()) { object propValue = prop.GetValue(myObj, null); string stringValue = propValue != null ? propValue.ToString() : String.Empty; tagBuilder.Attributes.Add(prop.Name, stringValue); }

Esto funciona muy bien, excepto que quiero que solo haga esto para tipos primitivos, como int , double , bool , etc., y otros tipos que no son primitivos, pero que se pueden serializar fácilmente como string . Quiero que ignore todo lo demás, como listas y otros tipos personalizados.

¿Alguien puede sugerir cómo hago esto? ¿O debo especificar los tipos que quiero permitir en algún lugar y activar el tipo de propiedad para ver si está permitido? Eso es un poco desordenado, así que estaría bien si hubiera una manera más ordenada.


Aquí hay otra opción viable.

public static bool CanDirectlyCompare(Type type) { return typeof(IComparable).IsAssignableFrom(type) || type.IsPrimitive || type.IsValueType; }


Así es como lo hice.

static class PrimitiveTypes { public static readonly Type[] List; static PrimitiveTypes() { var types = new[] { typeof (Enum), typeof (String), typeof (Char), typeof (Guid), typeof (Boolean), typeof (Byte), typeof (Int16), typeof (Int32), typeof (Int64), typeof (Single), typeof (Double), typeof (Decimal), typeof (SByte), typeof (UInt16), typeof (UInt32), typeof (UInt64), typeof (DateTime), typeof (DateTimeOffset), typeof (TimeSpan), }; var nullTypes = from t in types where t.IsValueType select typeof (Nullable<>).MakeGenericType(t); List = types.Concat(nullTypes).ToArray(); } public static bool Test(Type type) { if (List.Any(x => x.IsAssignableFrom(type))) return true; var nut = Nullable.GetUnderlyingType(type); return nut != null && nut.IsEnum; } }


Asumiendo que tienes una firma de función como esta:

void foo<T>()

Puede agregar una restricción genérica para permitir solo los tipos de valor:

void foo<T>() where T : struct

Tenga en cuenta que esto permite no solo tipos primitivos para T, sino también cualquier tipo de valor.


Desde @Ronnie Overby response y @jonathanconway comment, escribí este método que funciona para Nullable y excluyo las estructuras de usuario.

public static bool IsSimpleType(Type type) { return type.IsPrimitive || new Type[] { typeof(Enum), typeof(String), typeof(Decimal), typeof(DateTime), typeof(DateTimeOffset), typeof(TimeSpan), typeof(Guid) }.Contains(type) || Convert.GetTypeCode(type) != TypeCode.Object || (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) && IsSimpleType(type.GetGenericArguments()[0])) ; }

Con el siguiente TestCase:

struct TestStruct { public string Prop1; public int Prop2; } class TestClass1 { public string Prop1; public int Prop2; } [Test] public void Test1() { Assert.IsTrue(IsSimpleType(typeof(Enum))); Assert.IsTrue(IsSimpleType(typeof(String))); Assert.IsTrue(IsSimpleType(typeof(Char))); Assert.IsTrue(IsSimpleType(typeof(Guid))); Assert.IsTrue(IsSimpleType(typeof(Boolean))); Assert.IsTrue(IsSimpleType(typeof(Byte))); Assert.IsTrue(IsSimpleType(typeof(Int16))); Assert.IsTrue(IsSimpleType(typeof(Int32))); Assert.IsTrue(IsSimpleType(typeof(Int64))); Assert.IsTrue(IsSimpleType(typeof(Single))); Assert.IsTrue(IsSimpleType(typeof(Double))); Assert.IsTrue(IsSimpleType(typeof(Decimal))); Assert.IsTrue(IsSimpleType(typeof(SByte))); Assert.IsTrue(IsSimpleType(typeof(UInt16))); Assert.IsTrue(IsSimpleType(typeof(UInt32))); Assert.IsTrue(IsSimpleType(typeof(UInt64))); Assert.IsTrue(IsSimpleType(typeof(DateTime))); Assert.IsTrue(IsSimpleType(typeof(DateTimeOffset))); Assert.IsTrue(IsSimpleType(typeof(TimeSpan))); Assert.IsFalse(IsSimpleType(typeof(TestStruct))); Assert.IsFalse(IsSimpleType(typeof(TestClass1))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Char>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Guid>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Boolean>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Byte>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Int16>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Int32>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Int64>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Single>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Double>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<Decimal>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<SByte>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<UInt16>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<UInt32>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<UInt64>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<DateTime>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<DateTimeOffset>))); Assert.IsTrue(IsSimpleType(typeof(Nullable<TimeSpan>))); Assert.IsFalse(IsSimpleType(typeof(Nullable<TestStruct>))); }


Esto es lo que tengo en mi biblioteca. Los comentarios son bienvenidos

Primero compruebo IsValueType, ya que maneja la mayoría de los tipos, luego String, ya que es el segundo más común. No puedo pensar en un primitivo que no sea un tipo de valor, así que no sé si ese tramo del si alguna vez es golpeado.

Public Shared Function IsPersistable(Type As System.Type) As Boolean With TypeInformation.UnderlyingType(Type) Return .IsValueType OrElse Type = GetType(String) OrElse .IsPrimitive End With End Function Public Shared Function IsNullable(ByVal Type As System.Type) As Boolean Return (Type.IsGenericType) AndAlso (Type.GetGenericTypeDefinition() Is GetType(Nullable(Of ))) End Function Public Shared Function UnderlyingType(ByVal Type As System.Type) As System.Type If IsNullable(Type) Then Return Nullable.GetUnderlyingType(Type) Else Return Type End If End Function

Entonces puedo usarlo así:

Public Shared Function PersistableProperties(Item As System.Type) As IEnumerable(Of System.Reflection.PropertyInfo) Return From PropertyInfo In Item.GetProperties() Where PropertyInfo.CanWrite AndAlso (IsPersistable(PropertyInfo.PropertyType)) Select PropertyInfo End Function


Lo hacemos así en nuestro ORM:

Type t; bool isPrimitiveType = t.IsPrimitive || t.IsValueType || (t == typeof(string));

Sé que usar IsValueType no es la mejor opción (puedes tener tus propias estructuras muy complejas) pero funciona en 99% de los casos


Puede usar la propiedad Type.IsPrimitive , pero tenga cuidado porque hay algunos tipos que podemos pensar que son primitivos, pero no lo son, por ejemplo, Decimal y String .

Edición 1: código de muestra agregado

Aquí hay un código de muestra:

if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... ) { // Is Primitive, or Decimal, or String }

Editar 2: como comentarios de SLaks , hay otros tipos que quizás desee tratar como primitivos, también. Creo que tendrás que agregar estas variaciones una a una .

Edición 3: IsPrimitive = (Booleano, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Doble y Único), tipo Anther Primitive-Like para verificar (t == typeof (DateTime) )


Solo quiero compartir mi solución. Tal vez sea útil para cualquiera.

public static bool IsPrimitiveType(Type fieldType) { return fieldType.IsPrimitive || fieldType.Namespace.Equals("System"); }


También una buena posibilidad:

private static bool IsPrimitiveType(Type type) { return (type == typeof(object) || Type.GetTypeCode(type) != TypeCode.Object); }


Tenía la necesidad de serializar tipos para exportarlos a XML. Para hacer esto, itere a través del objeto y opté por campos primitivos, enum, value types o serializables. Este fue el resultado de mi consulta:

Type contextType = context.GetType(); var props = (from property in contextType.GetProperties() let name = property.Name let type = property.PropertyType let value = property.GetValue(context, (BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.Public), null, null, null) where (type.IsPrimitive || type.IsEnum || type.IsValueType || type.IsSerializable) select new { Name = name, Value = value});

Usé LINQ para repetir los tipos, luego obtuve su nombre y valor para almacenarlos en una tabla de símbolos. La clave está en la cláusula ''dónde'' que elegí para la reflexión. Elegí primitivos, enumerados, tipos de valores y tipos serializables. Esto permitió que las cadenas y los objetos DateTime aparecieran como esperaba.

¡Aclamaciones!


public static bool IsPrimitiveType(object myObject) { var myType = myObject.GetType(); return myType.IsPrimitive || myType.Namespace == null || myType.Namespace.Equals("System"); }

No olvides verificar el espacio de nombres NULL, porque los objetos anónimos no tienen espacio de nombres asignado