.net ID比较与参考比较

.net ID比较与参考比较,.net,performance,reference,comparison,.net,Performance,Reference,Comparison,我有一些实体框架对象,它们也由自己的ID标识 我更喜欢使用引用比较,这可能更可靠,尤其是对于尚未在DB上的对象 就性能而言,Int32 ID比较和ByRef对象比较之间的差距是什么?比较引用和比较int的性能大致相同。ID比较需要对堆栈进行额外的属性访问调用。但是,两者之间的性能差异可以忽略不计 然而,这不应该成为决定平等性的决定性因素。相等性应根据对象所表示的内容来确定。如果对象由其ID属性定义,则应使用ID属性确定相等性。如果对象由其值的组合定义,则应通过比较其每个组件值来确定相等性 为了更

我有一些实体框架对象,它们也由自己的ID标识

我更喜欢使用引用比较,这可能更可靠,尤其是对于尚未在DB上的对象


就性能而言,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
相等也并不总是合适的。价值平等也是如此。这两种情况都有,您必须决定什么最能代表您正在处理的数据。关于这方面的更多信息,提供了“实体”和“价值对象”(来自领域驱动设计方法学的概念)之间差异的一个非常基本的概念。

担心这种性能差异听起来像是过早的优化——实际上不太可能产生任何实际的差异。这取决于具体情况。访问该引用末尾的数据是否会导致缓存未命中,否则该缓存将不存在?如果不是,则忽略它。如果有,请对其进行配置,可能仍然忽略它。不可能出现缓存未命中。从数据库加载记录时,其所有字段都将被填充。所以,谢谢你:)担心这种性能差异听起来像是过早的优化——它真的不可能产生任何实际的影响。这取决于。在那之后访问数据是否意味着