c# - net - Determinar si la propiedad reflejada se puede asignar nula
reflection c# español (4)
Deseo descubrir automágicamente cierta información en una clase proporcionada para hacer algo similar a la entrada de formulario. Específicamente, estoy usando el reflejo para devolver un valor de PropertyInfo para cada propiedad. Puedo leer o escribir valores en cada propiedad de mi "formulario", pero si la propiedad se define como "int", no podría, y mi programa ni siquiera debería intentar, escribir un valor nulo.
¿Cómo puedo usar la reflexión para determinar si a una propiedad determinada se le puede asignar un valor nulo, sin escribir una declaración de cambio para verificar para cada tipo posible? En particular, quiero detectar la diferencia entre tipos encuadrados como "int" vs. "int?", Ya que en el segundo caso quiero poder escribir un valor nulo. IsValueType e IsByRef no parecen ver la diferencia.
public class MyClass
{
// Should tell me I cannot assign a null
public int Age {get; set;}
public DateTime BirthDate {get; set;}
public MyStateEnum State {get; set;}
public MyCCStruct CreditCard {get; set;}
// Should tell me I can assign a null
public DateTime? DateOfDeath {get; set;}
public MyFamilyClass Famly {get; set;}
}
Tenga en cuenta que necesito determinar esta información mucho antes de intentar escribir el valor, por lo que no es una opción utilizar el manejo de excepciones en SetValue.
Desde http://msdn.microsoft.com/en-us/library/ms366789.aspx
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
Type
sería su PropertyInfo.PropertyType
Marc y Jonas tienen partes para determinar si se puede asignar un tipo genérico nulo.
// A silly example. default(T) will return null if it is nullable. So no reason to check here. Except for the sake of having an example.
public U AssignValueOrDefault<U>(object item)
{
if (item == null)
{
Type type = typeof(U); // Type from Generic Parameter
// Basic Types like int, bool, struct, ... can''t be null
// Except int?, bool?, Nullable<int>, ...
bool notNullable = type.IsValueType ||
(type.IsGenericType && type.GetGenericTypeDefinition() != typeof(Nullable<>)));
if (notNullable)
return default(T);
}
return (U)item;
}
Nota: la mayoría de las veces puede verificar si la variable es nula. Luego usa el predeterminado (T). Devolverá nulo por defecto del objeto es una clase.
Necesita manejar referencias null
y Nullable<T>
, entonces (a su vez):
bool canBeNull = !type.IsValueType || (Nullable.GetUnderlyingType(type) != null);
Tenga en cuenta que IsByRef
es algo diferente, que le permite elegir entre int
y ref int
/ out int
.
PropertyInfo propertyInfo = ...
bool canAssignNull =
!propertyInfo.PropertyType.IsValueType ||
propertyInfo.PropertyType.IsGenericType &&
propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)