2017-07-07 73 views
1

对不起,文章的标题反序列化相同对象时获得一个现有的对象引用,不知道怎么去表达它更好..如何从磁盘

我有一个对象unit我救到文件系统使用MemoryStreamBinaryFormatter

现在我必须运行一个NUNIT测试,检查对象carcarloadedFromDisk是否相等。此测试失败,因为它看起来像在堆上有不同的引用。

是否有可能使反序列化对象carloadedFromDisk指向对象车的现有引用? 我能做些什么来使测试通过?

例子:

var car = new Car("Audi"); 
var unit = new Unit("GoldSmith", car); 

unit.save(); 
var carloadedFromDisk = Car.get(carId); // deserialized 

Assert.AreEqual(unit.Car, carloadedFromDisk); // <-- fails 

回答

1

是否有可能有反序列化对象carloadedFromDisk到 指向对象车的现有的参考?

这是不可能的。新实例在反序列化过程中创建。即使你可以通过现有的实例被反序列化器填充,那么你最终会得到一个与其本身相比(实际为true)的实例。

现在我必须运行一个NUNIT测试,检查carloadedFromDisk和 carloadedFromDisk是否相等。此测试失败,因为它看起来像 它们在堆上有不同的引用。

而不是比较引用,你应该比较值。在您的Car类中实施EqualsGetHashCode方法,以便Car实例的字段用于比较和散列生成。 Equals将被Assert.AreEqual断言。例如。如果您Car有两个属性:

public int Id { get; set; } 
public string Name { get; set; } 

public override bool Equals(object obj) 
{ 
    if (obj == null || GetType() != obj.GetType()) 
     return false; 

    Car other = (Car)obj; 
    return (Id == other.Id) && (Name == other.Name); 
} 

public override int GetHashCode() 
{ 
    unchecked 
    { 
     int hash = 19; 
     hash = hash * 23 + Id; 
     hash = hash * 23 + Name == null ? 0 : Name.GetHashCode(); 
     return hash; 
    } 
} 

延伸阅读:Implementing the Equals Method

+0

为什么使用19作为哈希的初始值,为什么你用23乘以散列,意外?感谢您的快速回复! – Legends

+1

@Lemends是素数 - 目的是获得良好的散列码分布,以避免所有项目进入字典或其他散列集合的相同存储桶。虽然人们说它[更好地使用大素数](https://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode) –