1

我试图在使用大量反射的环境中创建扩展方法。

这些方法的目的是重新创建 default() 在运行时所做的事情。

它适用于除那些 Nullable<> 类型之外的所有内容。甚至 ?-Types 也能正常工作。

我不知道如何找出分配给对象变量的值是否为 Nullable<> 而不是“常规值类型”

Nullable.GetUnderlyingType-Method 在这种情况下返回 null,但适用于 ?-Types。

我们知道 default(Nullable) == null。当 Nullable 分配为 0 时,我的扩展方法会产生错误的结果,因为 0 == default(int)。

我希望你能得到我在这里试图解释的内容,简而言之: - 我如何确定“随机”对象是否是 Nullable 而不是 int ?

该方法看起来像这样(为简单起见,删除了任何缓存)我从这里获取了部分如何检查对象是否可以为空?

public static bool IsDefault(this object obj)
{
    if(obj == null)
        return true;
    else
    {
        Type objType = obj.GetType(); // This gives int32 for Nullabe<int> !?!

        if(Nullable.GetUnderlyingType(objType) != null)
            return false;
        else if(objType.IsValueType)
            return Object.Equals(obj, Activator.CreateInstance(objType);
        else
            return false;
    }
}

为了更清楚,我不能使用通用的东西......

4

4 回答 4

3

你不能这样做,因为当你调用该方法时,可为空的结构被装箱为 be object,并成为要么 要么null一个Int32值。这在较早的答案中进行了解释:为什么 GetType 返回 System.Int32 而不是 Nullable<Int32>?

如果您的变量在调用此方法的地方被键入为对象,我认为您无法获得所需的信息 - 它已经被装箱了。

于 2013-07-03T17:07:41.450 回答
3

当一个可以为空的类型被装箱到一个object时,它可以为空的事实就丢失了:它要么变成一个普通的旧的int,要么变成一个普通的旧的null。如果您的对象已存储为 type object,则无法恢复它。

于 2013-07-03T17:08:11.097 回答
0

似乎您可以通过执行以下操作来确定类型是否可以为空:

public static bool IsDefault<T>( this T obj )
{
    var t = typeof( T );
    var isNullable = t.IsGenericType && t.GetGenericTypeDefinition() == typeof( Nullable<> );
    // ...
}

不过,您的方法必须是通用的才能正常工作。

于 2013-07-03T17:12:04.223 回答
-1

来自http://msdn.microsoft.com/en-us/library/ms366789.aspx

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {…}
于 2013-07-03T17:11:04.817 回答