为什么在C#中将结构体与NULL进行比较是合法的?

3

可能是重复问题:
C#允许将值类型与null进行比较

考虑下面这段使用TimeSpan(结构体)的代码:

// will not compile - illegal
TimeSpan ts = null;  

然而,下面的代码虽然表达式始终为false,但是它确实可以编译并且是合法的:
if (ts == null)
    Console.WriteLine("this line will never be hit");

有人可以告诉我为什么将结构体设置为NULL是无效的,但将其与NULL进行比较却是可以的吗?

https://dev59.com/FHI-5IYBdhLWcg3wFkOO, https://dev59.com/PXRB5IYBdhLWcg3wXWK2, https://dev59.com/-3M_5IYBdhLWcg3wymY0, https://dev59.com/7nI-5IYBdhLWcg3wMFW0 - nawfal
如果您无法将结构体与null进行比较,那么您会如何处理Nullable<T>? - Anthony Pegram
@AnthonyPegram: 更好的问题是,您将如何将Nullable<T>实现为struct?(当然,您不能这样做)。Nullable<T>可以被实现为引用类型。 - Ed S.
1
@EdS. 但是 Nullable<T> 确实 是一个结构体。 - phoog
@phoog:对,那就是我想表达的意思 :) - Ed S.
2个回答

7

这仍然是合法的,因为你可以重载struct类型的==操作符。

struct AmNull {
    public static bool operator ==(AmNull a, object b) {
        return b == null;
    }

    public static bool operator !=(AmNull a, object b) {
        return b != null;
    }
}

...

Console.WriteLine(new AmNull() == null); // True

3
我建议你选择这个回答作为被采纳的答案。它覆盖了我的回答,同时还详细解释了为什么存在这种行为。 - Ed S.

3

我无法通过编译:

struct Foo { }

class Program
{       
    static void Main( string[] args )
    {
        var f = new Foo();
        if( f == null ) { }
    }
}

错误 1:运算符“==”不能应用于类型为“ConsoleApplication3.Foo”和“null”的操作数。

该错误表示在使用“==”运算符比较一个对象(Foo)和空值(null)时出错。

@AngryHacker:这是因为TimeSpan重载了==运算符(我一开始没有注意到)。我的观点是,你的问题“为什么在C#中将结构体与NULL进行比较是合法的?”不完整;除非你重载相等运算符来接受它,否则你不能这样做。minitech有一个更好的回答。 - Ed S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接