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 lo quiero sólo para hacer esto para los tipos primitivos, como int
, double
, bool
etc., y otros tipos que no son primitivos, pero se puede 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 necesito 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, por lo que sería bueno si hubiera una forma más ordenada.
c#
reflection
primitive-types
DaveDev
fuente
fuente
System.String
No es un tipo primitivo.Respuestas:
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
yString
.Edición 1: código de muestra agregado
Aquí hay un código de muestra:
Edición 2: Como comenta @SLaks , hay otros tipos que quizás también quieras tratar como primitivos. Creo que tendrás que agregar estas variaciones una por una .
Edición 3: IsPrimitive = (Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double y Single), tipo Anther Primitive-Like para comprobar (t == typeof (DateTime ))
fuente
DateTime
,TimeSpan
yDateTimeOffset
.||
), no el bit a bit o (|
).Acabo de encontrar esta pregunta mientras buscaba una solución similar, y pensé que podría estar interesado en el siguiente enfoque usando
System.TypeCode
ySystem.Convert
.Es fácil serializar cualquier tipo que esté asignado a
System.TypeCode
otro que no seaSystem.TypeCode.Object
, por lo que podría hacer: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.
fuente
Guid
para mis propios fines (como primitivo en mi definición).Lo hacemos así en nuestro ORM:
Sé que usar
IsValueType
no es la mejor opción (puede tener sus propias estructuras muy complejas) pero funciona en 99% de los casos (e incluye Nullables).fuente
decimal
en ese sentido. Pero, ¿hay algún tipo para el queIsPrimitive
regresetrue
peroIsValueType
regresefalse
? Si no existe tal tipo, entonces lat.IsPrimitive
prueba es innecesaria.IsValueType
establecido en verdadero, porIsPrimitive
lo que no es necesario verificarlo . ¡Salud!Desde la respuesta de @Ronnie Overby y el comentario de @jonathanconway, escribí este método que funciona para Nullable y excluyo las estructuras de usuario.
Con el siguiente TestCase:
fuente
Enum
no es compatible, pruébeloenum MyEnum { EnumValue }
y utilíceloMyEnum
. @Jonathan también está usandotype.IsValueType
. Con esoEnums
se detectan correctamente, pero tambiénStructs
. Así que ten cuidado con las primitivas que quieres.type.IsValueType
, ¿por qué simplemente no agregartype.IsEnum
?type.IsEnum
También es posible. He sugerido una edición en tu publicación :)Así es como lo hice.
fuente
IsAssignableFrom
en su prueba en lugar de contener?También una buena posibilidad:
fuente
Type
tiene una propiedad llamada IsPrimitive . Deberías usar eso en su lugar.String
tampoco loDecimal
son los primitivos.Suponiendo que tiene una firma de función como esta:
Puede agregar una restricción genérica para permitir solo tipos de valores:
Tenga en cuenta que esto no solo permite tipos primitivos para T, sino también cualquier tipo de valor.
fuente
Tenía la necesidad de serializar tipos para exportarlos a XML. Para hacer esto, realicé una iteración a través del objeto y opté por campos que eran primitivos, enumeración, tipos de valor o serializables. Este fue el resultado de mi consulta:
Usé LINQ para recorrer los tipos y luego obtener 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í tipos primitivos, enumerados, de valor y tipos serializables. Esto permitió que las cadenas y los objetos DateTime aparecieran como esperaba.
¡Salud!
fuente
Esto es lo que tengo en mi biblioteca. Comentarios son bienvenidos
Primero verifico 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 una primitiva que no sea un tipo de valor, por lo que no sé si esa parte del si alguna vez es golpeada.
Entonces puedo usarlo así:
fuente
Solo quiero compartir mi solución. Quizás sea útil para cualquiera.
fuente
IsPrimitiveType(typeof(System.AccessViolationException)) == true
namespace System { class MyNonPrimitiveType { } }
No olvide verificar el espacio de nombres NULL, porque los objetos anónimos no tienen espacio de nombres asignado
fuente
Aquí hay otra opción viable.
fuente