代码之家  ›  专栏  ›  技术社区  ›  Felipe Pessoto

当将t与空进行比较,t是一个结构时,clr会做什么?

  •  8
  • Felipe Pessoto  · 技术社区  · 14 年前
    private static void SaveOrRemove<T>(string key, T value)
    {
        if (value == null)
        {
            Console.WriteLine("Remove: " + key);
        }
    
        //...
    }
    

    如果我调用传递0到值: SaveOrRemove("MyKey", 0) ,条件 value == null 是假的,则clr不生成 value == default(T) . 到底发生了什么?

    3 回复  |  直到 14 年前
        1
  •  10
  •   Jon Skeet    14 年前

    当t是不可为空的值类型时,jit编译器基本上会删除与空值的任何比较,假定它们都为假。(可以为空的值类型将与该类型的空值进行比较,这可能是您所期望的。)

    如果你 希望 与默认值相比,您可以使用:

    if (EqualityComparer<T>.Default.Equals(value, default(T))
    {
        ...
    }
    
        2
  •  5
  •   Eric Lippert    14 年前

    您的问题在C规范第7.9.6节中得到了回答:

    如果类型参数类型的操作数 将t与空值进行比较,并将运行时 t的类型是值类型,结果 这一比较是错误的。

        3
  •  0
  •   Chris Charabaruk    14 年前

    如果你想要 default(T) 你必须说出来,不是 null 它有它自己的意义。如果你真的想通过 无效的 在替换值类型时,应使用 Nullable<T> 相反。

    因此,您的代码将变为:

    private static void SaveOrRemove<T>(string key, Nullable<T> value)
    {
        if (!value.HasValue()) // is null
        {
            Console.WriteLine("Remove: " + key);
        }
        else
        {
            T val = value.Value;
            // ...
        }
    }
    

    注意 可以为空<t> 只对值类型(结构、“builtins”而不是字符串)有用;对于引用类型,无论如何都不能使用它。

    MSDN link