可能是重复问题:
C#中比较值类型和null是否可以
我在多线程环境下开发 Windows 应用程序时,有时会遇到异常 "Invoke 或 BeginInvoke 无法在控件的窗口句柄创建之前调用。" 所以我想只需添加这行代码:
if(this.Handle != null)
{
//BeginInvokeCode
}
但是那并没有解决问题。所以我进一步研究后发现,IntPtr(Form.Handle 所属的类型)是一个不能为 null 的结构体。以下是最终有效的修复方法:
if(this.Handle != IntPtr.Zero)
{
//BeginInvokeCode
}
接着我意识到,当我检查它是否为null时,为什么它还可以编译通过呢?所以我决定自己试一下:
public struct Foo { }
然后:
static void Main(string[] args)
{
Foo f = new Foo();
if (f == null) { }
}
然后,果然编译出错并提示“错误 1 运算符“==”不能应用于类型为“ConsoleApplication1.Foo”和“”的操作数”。好吧,我开始查看IntPtr的元数据,并将IntPtr结构中的所有内容添加到我的Foo结构中(ISerializable,ComVisible),但仍未解决问题。最后,当我添加了==和!=的运算符重载时,它就起作用了:
[Serializable]
[ComVisible(true)]
public struct Foo : ISerializable
{
#region ISerializable Members
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
#endregion
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public static bool operator ==(Foo f1, Foo f2) { return false; }
public static bool operator !=(Foo f1, Foo f2) { return false; }
}
这最终编译成功了:
static void Main(string[] args)
{
Foo f = new Foo();
if (f == null) { }
}
我的问题是为什么?如果你覆盖了 == 和 !=,为什么可以将其与 null 进行比较? == 和 != 的参数仍然是不可空的 Foo 类型,那么为什么突然允许这样做呢?