Abe*_*bel 2 .net c# null this referenceequals
请考虑以下我正在审核的代码:
public override bool Equals(object other)
{
return !object.ReferenceEquals(null, this)
&& (object.ReferenceEquals(this, other)
|| ((other is MyType) && this.InternalEquals((MyType)other)));
}
Run Code Online (Sandbox Code Playgroud)
这段代码的第一行引发了我的好奇心.每当this为null时,该方法应返回false.现在我很确定程序员打算用!object.ReferenceEquals(other, null)快捷方式编写null,但是他坚持认为this可以为null.我坚持认为它不能(除非有人使用直接内存操作).我们应该留下吗?
虽然我肯定不会正常检查this为无效,这是可能的,没有任何实际的内存污秽-只是有点反思:
using System;
public class Test
{
public void CheckThisForNullity()
{
Console.WriteLine("Is this null? {0}", this == null);
}
static void Main(string[] args)
{
var method = typeof(Test).GetMethod("CheckThisForNullity");
var openDelegate = (Action<Test>) Delegate.CreateDelegate(
typeof(Action<Test>), method);
openDelegate(null);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,生成IL,call而不是callvirt在空目标上调用实例方法.完全合法,不是C#编译器通常会做的事情.
这与终结无关,终结本身就是毛茸茸的,但却以不同的方式.如果CLR可以证明你不会使用实例中的任何字段(我强烈希望包含this引用),那么在实例方法执行时可以运行终结器.
至于提供的代码 - 不,这看起来只是一个错误.我会把它重写为:
public override bool Equals(object other)
{
return Equals(other as MyType);
}
public bool Equals(MyType other)
{
if (ReferenceEquals(other, null))
{
return false;
}
// Now perform the equality check
}
Run Code Online (Sandbox Code Playgroud)
...假设这MyType是一个类,而不是结构.请注意我如何使用具有正确参数类型的另一个公共方法 - 我将同时实现IEquatable<MyType>.