我如何检查一个给定的对象是否为空,换句话说,如何实现以下方法…

bool IsNullableValueType(object o)
{
    ...
}

我正在寻找可空值类型。我没有想到引用类型。

//Note: This is just a sample. The code has been simplified 
//to fit in a post.

public class BoolContainer
{
    bool? myBool = true;
}

var bc = new BoolContainer();

const BindingFlags bindingFlags = BindingFlags.Public
                        | BindingFlags.NonPublic
                        | BindingFlags.Instance
                        ;


object obj;
object o = (object)bc;

foreach (var fieldInfo in o.GetType().GetFields(bindingFlags))
{
    obj = (object)fieldInfo.GetValue(o);
}

obj现在指向bool类型(System.Boolean)的值为true的对象。我真正想要的是一个Nullable<bool>类型的对象

所以现在我决定检查o是否为空,并在obj周围创建一个可空的包装器。


当前回答

最简单的方法是:

public bool IsNullable(object obj)
{
    Type t = obj.GetType();
    return t.IsGenericType 
        && t.GetGenericTypeDefinition() == typeof(Nullable<>);
}

其他回答

我认为使用微软对IsGenericType的建议测试是好的,但在GetUnderlyingType的代码中,微软使用了一个额外的测试,以确保你没有通过泛型类型定义Nullable<>:

 public static bool IsNullableType(this Type nullableType) =>
    // instantiated generic type only                
    nullableType.IsGenericType &&
    !nullableType.IsGenericTypeDefinition &&
    Object.ReferenceEquals(nullableType.GetGenericTypeDefinition(), typeof(Nullable<>));

你可以用:

return !(o is ValueType);

... 但是对象本身不是可空的,而是类型。你打算怎么用这个?

我想到的最简单的解决方案是实现微软的解决方案(如何:识别可空类型(c#编程指南))作为扩展方法:

public static bool IsNullable(this Type type)
{
    return Nullable.GetUnderlyingType(type) != null;
}

然后可以这样调用:

bool isNullable = typeof(int).IsNullable();

这似乎也是访问IsNullable()的一种逻辑方式,因为它适合Type类的所有其他IsXxxx()方法。

这个版本:

缓存结果更快, 不需要不必要的变量,如Method(T obj) 并不复杂:), 只是静态泛型类,只有一次计算字段

:

public static class IsNullable<T>
{
    private static readonly Type type = typeof(T);
    private static readonly bool is_nullable = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
    public static bool Result { get { return is_nullable; } }
}

bool is_nullable = IsNullable<int?>.Result;

以下是我想出的,因为其他一切似乎都失败了-至少在PLC -便携式类库/ .NET核心>= c# 6

解决方案:为任何Type T和Nullable<T>扩展静态方法,并使用与底层类型匹配的静态扩展方法将被调用,并优先于泛型T扩展方法。

T:

public static partial class ObjectExtension
{
    public static bool IsNullable<T>(this T self)
    {
        return false;
    }
}

和对于Nullable<T>

public static partial class NullableExtension
{
    public static bool IsNullable<T>(this Nullable<T> self) where T : struct
    {
        return true;
    }
}

使用Reflection和type.IsGenericType…不能在我当前的。net运行时上运行。MSDN文档也没有帮助。

如果类型。IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)){…}

部分原因是。net Core中的反射API已经发生了相当大的变化。