我只是写了一段代码,它的行为与我预期的完全不同。
它似乎告诉我,我对对象还一无所知,所以我谦虚地求助于堆栈溢出同行的智慧,为我指明了正确的方向。
这是让我困惑的代码:
[Test]
public void TestMySanity()
{
var oldSet = new Identifier[0];
var newSet = new[]
{
new Identifier("1"),
new Identifier("2")
};
var changes = uut.TrackChanges(oldSet, newSet, x => x).ToArray();
ChangeRecord<Identifier> xx = changes.FirstOrDefault(x => x.New != null && x.Old != null);
if (xx != null)
{
if (xx.Old != null && ((object) xx.Old) == null)
{
Console.WriteLine("How can something be not null and null at the same time?");
}
Assert.Fail("PS: this test expects a change record with Old = null and New = an Identifier");
}
}
只是要清楚-> 此代码进入不应该发生的
Console.WriteLine(...)
...我试图让一些事情变得更明智:
Console.WriteLine("Is Object? " + (xx.Old is Object)); // = false
Console.WriteLine("Reference Equals? " + Object.ReferenceEquals(xx.Old, null)); // = true
try { Console.WriteLine(xx.Old.GetType().Name); }
catch (Exception ex)
{ Console.WriteLine("GetType() -> " + ex.Message);}
//Throws: Object reference not set to an instance of an object.
关于这个问题的评论似乎表明类标识符对于这个问题很重要,所以这里是:
public class Identifier : IComparable, IComparable<Identifier>, IEquatable<Identifier>
{
//Var
protected readonly IComparable Key;
//Constructor
public Identifier(IComparable key)
{
Key = key;
if (key == null) throw new ArgumentNullException("key");
}
//Hashcode (Must be overridden when equals is overridden.)
public override int GetHashCode()
{
return Key.GetHashCode();
}
public override string ToString()
{
return "[" + Key + "]";
}
//Compare
public virtual int CompareTo(object obj)
{
return CompareTo((Identifier)obj);
}
public virtual int CompareTo(Identifier other)
{
if (other == null) return 1;
return Key.CompareTo(other.Key);
}
//Equals
public override bool Equals(object obj)
{
return Equals((obj as Identifier));
}
public virtual bool Equals(Identifier other)
{
if (ReferenceEquals(null, other)) return false;
return Key.Equals(other.Key);
}
//Can be done because a Identifier is immutable
public static bool operator ==(Identifier A, Identifier B)
{
if (ReferenceEquals(A, null)) return false;
return A.Equals(B);
}
public static bool operator !=(Identifier A, Identifier B)
{
return !(A == B);
}
}
最佳答案
发现错误:
public static bool operator ==(Identifier A, Identifier B)
{
if (ReferenceEquals(A, null)) return false;
return A.Equals(B);
}
如果
B
是 null
会发生什么? A == B
应该返回 true
,遗憾的是您的比较将 return false
;将其更改为:
if (ReferenceEquals(A, null)) return ReferenceEquals(B, null);
return A.Equals(B);
总的来说,关键是通过像
object
那样强制转换为 ((object) xx.Old) == null
,你强制 C# 编译器使用 object==
运算符,它只是执行 object.ReferenceEquals(A, B)
,所以你绕过了你的错误代码。关于c# - (x.y != null && ((object)x.y) == null) 怎么可能是真的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36221113/