.net ID比较与参考比较
我有一些实体框架对象,它们也由自己的ID标识 我更喜欢使用引用比较,这可能更可靠,尤其是对于尚未在DB上的对象.net ID比较与参考比较,.net,performance,reference,comparison,.net,Performance,Reference,Comparison,我有一些实体框架对象,它们也由自己的ID标识 我更喜欢使用引用比较,这可能更可靠,尤其是对于尚未在DB上的对象 就性能而言,Int32 ID比较和ByRef对象比较之间的差距是什么?比较引用和比较int的性能大致相同。ID比较需要对堆栈进行额外的属性访问调用。但是,两者之间的性能差异可以忽略不计 然而,这不应该成为决定平等性的决定性因素。相等性应根据对象所表示的内容来确定。如果对象由其ID属性定义,则应使用ID属性确定相等性。如果对象由其值的组合定义,则应通过比较其每个组件值来确定相等性 为了更
就性能而言,Int32 ID比较和ByRef对象比较之间的差距是什么?比较引用和比较
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相等,那么这是可以的,因为我们知道它们应该指同一个人(和同一数据源)。然后,我们可以通过放弃这两个实例并从数据库中重新加载ID==12的Lady
,来解析哪个Lady
实例当前是正确的。相反,如果我们使用引用相等或值相等,我们最终会保存这两个对象,可能会覆盖错误的数据。此外,即使两个实例中的数据都相同,而且我们只有两个实例,因为我们意外地从数据库中加载了两次JaneSmith
,引用相等性检查也会返回false。似乎,newlady(12,“Jane”).Equals(newlady(12,“Jane”))
应该返回false是不对的。这也使得缓存几乎不可能,因为您永远无法确定记录是否已被缓存
一般来说,使用引用相等来比较持久对象是一个坏主意。然而,ID
相等也并不总是合适的。价值平等也是如此。这两种情况都有,您必须决定什么最能代表您正在处理的数据。关于这方面的更多信息,提供了“实体”和“价值对象”(来自领域驱动设计方法的概念)之间差异的基本概念。比较参考和比较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相等,那么这是可以的,因为我们知道它们应该指同一个人(和同一数据源)。然后,我们可以通过放弃这两个实例并从数据库中重新加载ID==12的Lady
,来解析哪个Lady
实例当前是正确的。相反,如果我们使用引用相等或值相等,我们最终会保存这两个对象,可能会覆盖错误的数据。此外,即使两个实例中的数据都相同,而且我们只有两个实例,因为我们意外地从数据库中加载了两次JaneSmith
,引用相等性检查也会返回false。似乎,newlady(12,“Jane”).Equals(newlady(12,“Jane”))
应该返回false是不对的。这也使得缓存几乎不可能,因为您永远无法确定记录是否已被缓存
一般来说,使用引用相等来比较持久对象是一个坏主意。然而,ID
相等也并不总是合适的。价值平等也是如此。这两种情况都有,您必须决定什么最能代表您正在处理的数据。关于这方面的更多信息,提供了“实体”和“价值对象”(来自领域驱动设计方法学的概念)之间差异的一个非常基本的概念。担心这种性能差异听起来像是过早的优化——实际上不太可能产生任何实际的差异。这取决于具体情况。访问该引用末尾的数据是否会导致缓存未命中,否则该缓存将不存在?如果不是,则忽略它。如果有,请对其进行配置,可能仍然忽略它。不可能出现缓存未命中。从数据库加载记录时,其所有字段都将被填充。所以,谢谢你:)担心这种性能差异听起来像是过早的优化——它真的不可能产生任何实际的影响。这取决于。在那之后访问数据是否意味着