Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 确定反射属性是否可以指定为null_C#_.net_Reflection - Fatal编程技术网

C# 确定反射属性是否可以指定为null

C# 确定反射属性是否可以指定为null,c#,.net,reflection,C#,.net,Reflection,我希望自动发现所提供类的一些信息,以便执行类似于表单条目的操作。具体来说,我使用反射为每个属性返回PropertyInfo值。我可以从我的“表单”中读取或写入每个属性的值,但是如果属性被定义为“int”,我将无法,我的程序甚至不应该尝试写入空值 如何使用反射来确定是否可以为给定属性分配空值,而不必编写switch语句来检查每种可能的类型?我特别想检测装箱类型之间的差异,比如“int”和“int?”,因为在第二种情况下,我确实希望能够写入空值。IsValueType和IsByRef似乎没有区别 p

我希望自动发现所提供类的一些信息,以便执行类似于表单条目的操作。具体来说,我使用反射为每个属性返回PropertyInfo值。我可以从我的“表单”中读取或写入每个属性的值,但是如果属性被定义为“int”,我将无法,我的程序甚至不应该尝试写入空值

如何使用反射来确定是否可以为给定属性分配空值,而不必编写switch语句来检查每种可能的类型?我特别想检测装箱类型之间的差异,比如“int”和“int?”,因为在第二种情况下,我确实希望能够写入空值。IsValueType和IsByRef似乎没有区别

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;}
}
请注意,我需要在实际尝试写入值之前很久确定此信息,因此使用围绕SetValue的异常处理不是一个选项。

From

if(type.IsGenericType&&type.GetGenericTypeDefinition()==typeof(可空))
Type
将是您的
PropertyInfo.PropertyType

PropertyInfo-PropertyInfo=。。。
PropertyInfo propertyInfo = ...
bool canAssignNull = 
    !propertyInfo.PropertyType.IsValueType || 
    propertyInfo.PropertyType.IsGenericType &&
        propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)
布尔卡纳西零= !propertyInfo.PropertyType.IsValueType | | propertyInfo.PropertyType.IsGenericType&& propertyInfo.PropertyType.GetGenericTypeDefinition()==typeof(可为空)
您需要处理
null
引用和
null
,因此(依次):


请注意,
IsByRef
有所不同,它允许您在
int
ref int
/
out int

之间进行选择,Marc和Jonas都有部分来确定泛型类型是否可以分配为null

// 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;
}
//一个愚蠢的例子。如果默认值(T)可为null,则它将返回null。所以没有理由在这里检查。除非是为了树立榜样。
public U Assignment Valuer默认值(对象项)
{
如果(项==null)
{
Type Type=typeof(U);//来自泛型参数的类型
//int、bool、struct等基本类型不能为null
//除了int?,bool?,Nullable。。。
bool notNullable=type.IsValueType||
(type.IsGenericType&&type.GetGenericTypeDefinition()!=typeof(可空));
如果(不可为空)
返回默认值(T);
}
退货(U)项;
}

注意:大多数情况下,您可以检查变量是否为null。然后使用默认值(T)。默认情况下,如果对象是一个类,它将返回null。

但它只返回可为null的值。适用于DateTime?,但不适用于MyFamilyClass,因为这不是泛型,但仍然是一种可以分配空值的类型结合Marc的答案,这有助于mestring可以为空,但不可为空。我没有想到这一点,但我确实针对is数组测试了您的答案,例如int[](可以分配空值)。你的答案在这种情况下也适用。数组是引用类型,因此它们与类的工作方式相同。我认为应该注意的是,在OP中,有使用int的示例?和DateTime?,因此第一次检查将返回true(!type.IsValueType)。与MSDN中给出的方法相比,我更喜欢这种方法,但我很好奇为什么您添加了一个似乎是多余的检查。也许,因为你想处理所有超出要求的情况?@pqsk,因为问题是“…可以分配为空”;需要考虑参考types@MarcGravell这只是巧合,我没有跟踪你。我无法访问
IsValueType
,但我确实在调试器中找到了它。我必须使用强制转换吗?使用PropertyInfo比直接使用类型有更多的开销。但是,如果您需要其他功能,可能会有所帮助。
bool canBeNull = !type.IsValueType || (Nullable.GetUnderlyingType(type) != null);
// 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;
}