我有一些Entity Framework对象,这些对象也由他们自己的ID标识。
我更喜欢使用可能更可靠的参考比较,特别是对于不在DB上的对象。
Int32 ID比较和 ByRef对象比较在性能方面的差距是什么?
答案 0 :(得分:1)
比较参考和比较int
的表现大致相同。 ID
比较需要在堆栈上进行额外的属性访问调用。但是,两者之间的性能差异可以忽略不计。
但是,这不应该是您如何确定平等的决定因素。应根据对象所代表的内容确定平等性。如果对象由其ID
属性定义,则应使用ID
属性来确定相等性。如果对象是由其值的组合定义的,那么您应该通过比较每个组件值来确定相等性。
为了更好地理解我在说什么,请考虑以下课程作为示例:
public class Lady {
public Lady(int id, string name, bool isMarried){
this.ID = id;
this.Name = name;
}
public int ID { get; private set; }
public string Name { get; set; }
public override int Equals(object other){ /* What goes here? */ }
public override int GetHashCode(){ /* What goes here? */ }
}
想象一下,您的应用使用Lady
类,如:
void Main(){
var JaneSmith = new Lady(id:12,name:"Jane Smith");
var JaneSmithJones = new Lady(id:12,name:"Jane Smith-Jones");
}
在这种情况下,这两个对象实际上可能是指同一个人。也许JaneSmith
是在Jane结婚并改名之前创建并缓存的。但是,现在她的名字已经改变了,现在价值和参考比较都会失败。但是,如果我们使用ID相等,那么这是可以的,因为我们知道他们应该引用同一个人(和相同的数据源)。然后,我们可以通过放弃两个实例并从数据库重新加载Lady
Lady
来解析当前哪个ID == 12
实例是正确的。相反,如果我们使用引用相等或值相等,我们最终会保存两个对象,可能会覆盖错误的数据。此外,即使两个实例中的数据相同而且我们只有两个实例,因为我们意外地从数据库中加载JaneSmith
两次,引用相等性检查将返回false。 new Lady(12,"Jane").Equals(new Lady(12,"Jane"))
应该返回false,这似乎是不对的。它也使得缓存几乎不可能,因为你永远无法确定记录是否已被缓存。
通常,使用引用相等性比较持久对象也是一个坏主意。但是,ID
平等并不总是合适的。价值平等也不是。两种情况都有,您必须确定最适合您所操作数据的内容。有关这方面的更多信息,this article提供了“实体”和“价值对象”(域驱动设计方法中的概念)之间差异的基本概念。