我如何检查一个给定的对象是否为空,换句话说,如何实现以下方法…
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周围创建一个可空的包装器。
以下是我想出的,因为其他一切似乎都失败了-至少在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已经发生了相当大的变化。
nullable有两种类型:nullable <T>和reference-type。
Jon纠正了我,如果是盒装的,很难得到类型,但你可以用泛型:
那么下面呢?这实际上是在测试类型T,但是使用obj参数纯粹是为了泛型类型推断(以便于调用)——尽管没有obj参数,它几乎可以完全相同地工作。
static bool IsNullable<T>(T obj)
{
if (obj == null) return true; // obvious
Type type = typeof(T);
if (!type.IsValueType) return true; // ref-type
if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T>
return false; // value-type
}
但是如果你已经将值装箱到一个对象变量中,这就不能很好地工作了。
微软文档:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/how-to-identify-a-nullable-type