【问题标题】:C# How to check if an object is nullable [duplicate]C#如何检查一个对象是否可以为空[重复]
【发布时间】:2017-01-02 11:50:22
【问题描述】:

在堆栈溢出中看到一个问答

How to check if an object is nullable?

我无法在上面发表评论,因为我没有超过 50 个 cmets,这就是我在这里提问的原因。

if(Nullable.GetUnderlyingType(myType) !=null)
{
   // It's Nullable
}

如果 myType 是 system.string

Nullable.GetUnderlyingType(myType) 

返回空值

我认为 System.string 可以为空!

【问题讨论】:

  • 您是否尝试阅读答案和所有代码,而不是复制看起来相关的行? Nullable.GetUnderlyingType() 仅适用于值类型。
  • 一个对象总是可以为空的,因为它是一个参考值

标签: c#


【解决方案1】:

调用Nullable.GetUnderlyingType() 不会返回任何对typeof(string) 有意义的信息。 documentation 提到:

返回指定可为空类型的基础类型参数。

返回值

nullableType参数的类型实参,如果nullableType参数是封闭的泛型可为空类型;否则为空。

换句话说,只有当你实际传递一个实现Nullable<T>的类型时,它才会返回有用的东西,例如int?bool?等等。 是这里“可空类型”的意思。

您还可以在Marc's answer to the question you link to的代码中看到它的预期用途:

static bool IsNullable<T>(T obj)
{
    // ...
    if (!type.IsValueType) return true; // ref-type
    if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T>
}

【讨论】:

    【解决方案2】:

    Nullable&lt;T&gt; - 是一个特殊的结构,所以System.string 不是Nullable&lt;T&gt;System.string 是一个类。所有类都可以为空。 所以,

    if (myType.IsClass)
    {
        //can be null
    }
    

    【讨论】:

      【解决方案3】:

      System.String(或字符串)是一个引用类型。这意味着,这种类型的实例可以是null。 Nullables 是一种将此功能添加到值类型(如基本类型 boolint 等)的方法。

      【讨论】:

        【解决方案4】:

        所有引用类型都可以设置为null,但不属于Nullable&lt;T&gt;类型,可以使用!myType.IsValueType检查一个类型是否为引用类型

        【讨论】:

          【解决方案5】:

          Nullable 是一个类型,而不是一个类型的属性。 System.String 可以为空,但它不是Nullable,不像int?,它是Nullable&lt;System.Int32&gt; 的快捷方式。 C# 中的所有引用类型都可以为空(可以传递空引用),而Nullable 类型只能接受不可为空的值类型作为参数。

          如果您想检查给定类型是否可以接受 null 作为值,您可以执行以下操作:

          bool CanBeNull<T>()
          {
            return default(T) == null;
          }
          

          当然,这已经假设默认值为空值,但不一定如此;但它适用于引用类型和Nullable 值类型。如果您必须处理接受 null 但不作为默认值的值类型,则必须专门添加它。除了实际尝试分配 null 值之外,没有真正确定且简单的方法来检查给定类型是否可以分配为 null。

          确实,“可以分配为空”的含义在很大程度上取决于编译器。例如,像int? someValue = null; 这样的操作实际上调用了int? 的构造函数——它相当于int? someValue = new int?();

          如果你在编译时不知道类型(所以你不能使用泛型),你可以添加一个检查给定类型是否是值类型:

          if (!type.IsValueType) // Can be assigned null
          

          确保正确对待类、值类型和接口。当然,仅仅能够将null 值分配给本地/字段并不意味着它一定是有效值。最终,决定权在你。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-08-06
            • 1970-01-01
            • 1970-01-01
            • 2020-10-05
            • 2013-10-11
            • 1970-01-01
            • 2017-08-08
            相关资源
            最近更新 更多