Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 确定除两个属性外,两个实例是否相同_C#_Object_Comparison_Equals - Fatal编程技术网

C# 确定除两个属性外,两个实例是否相同

C# 确定除两个属性外,两个实例是否相同,c#,object,comparison,equals,C#,Object,Comparison,Equals,我有一个有十个属性的类,我正在寻找除了两个特定属性之外,在这些属性中具有相同值的对象 我想扩展一个基类,它有我想要比较的八个属性,然后扩展这个基类,调用baseEquals方法 确定这一点的代码密集度最低的方法是什么?每当您希望比较自定义类的两个实例的值相等(即两个对象具有相同的值)而不是引用质量(两个对象引用引用相同的基础对象)时,在设计对象时必须考虑到这一点。有一个问题。简而言之,它涉及到实现System.IEquatable接口,该接口定义了一个签名为bool Equals(MyClass

我有一个有十个属性的类,我正在寻找除了两个特定属性之外,在这些属性中具有相同值的对象

我想扩展一个基类,它有我想要比较的八个属性,然后扩展这个基类,调用base
Equals
方法


确定这一点的代码密集度最低的方法是什么?

每当您希望比较自定义类的两个实例的值相等(即两个对象具有相同的值)而不是引用质量(两个对象引用引用相同的基础对象)时,在设计对象时必须考虑到这一点。有一个问题。简而言之,它涉及到实现
System.IEquatable
接口,该接口定义了一个签名为
bool Equals(MyClass other)
的方法。当
other
具有与
对象相同的“值”时,实现此方法以返回
true
。下面是一个简单对象的基本示例,它有4个属性决定其值相等性:

class MyClass : IEquatable<MyClass>
{
    public int ImportantProperty1 { get; set; }
    public int ImportantProperty2 { get; set; }
    public int ImportantProperty3 { get; set; }
    public int ImportantProperty4 { get; set; }
    public int NonImportantProperty { get; set; }

    public bool Equals(MyClass other)
    {
        return
            (!Object.ReferenceEquals(this, null)) &&
            (this.ImportantProperty1 == other.ImportantProperty1) &&
            (this.ImportantProperty2 == other.ImportantProperty2) &&
            (this.ImportantProperty3 == other.ImportantProperty3) &&
            (this.ImportantProperty4 == other.ImportantProperty4);
    }
}
这是最低限度。但是,如链接文章中所提到的,您可能需要考虑以下优化:

  • 重写
    虚拟对象.Equals(Object)
    方法,以便调用特定于类型的Equals方法。这将允许您将
    MyClass
    与其他类型的对象进行比较:

    public override bool Equals(object obj)
    {
        return this.Equals(obj as MyClass);
    }
    
  • bool Equals(MyClass)
    方法添加一个检查,查看
    other
    是否引用了与
    this
    相同的对象:

        public bool Equals(MyClass other)
        {
            if (Object.ReferenceEquals(this, other))
                return true;    
    
            return
                (!Object.ReferenceEquals(this, null)) &&
                (this.ImportantProperty1 == other.ImportantProperty1) &&
                (this.ImportantProperty2 == other.ImportantProperty2) &&
                (this.ImportantProperty3 == other.ImportantProperty3) &&
                (this.ImportantProperty4 == other.ImportantProperty4);
        }
    
  • 重写
    Object.GetHashCode()
    方法,以便两个值相等的对象生成相同的哈希代码。这是我在此类场景中实现此方法时使用的模式:

    public override int GetHashCode()
    {
        unchecked {
            int hash = 17;
            hash = hash * 23 + ImportantProperty1.GetHashCode();
            hash = hash * 23 + ImportantProperty2.GetHashCode();
            hash = hash * 23 + ImportantProperty3.GetHashCode();
            hash = hash * 23 + ImportantProperty4.GetHashCode();
            return hash;
        }
    }
    
  • 可选地覆盖
    =
    =运算符。除非覆盖它们,否则它们将默认为引用相等。有关示例,请参阅链接文章

  • 下面是我的完整示例:

    namespace ValueEquality
    {
    
        class MyClass : IEquatable<MyClass>
        {
            public int ImportantProperty1 { get; set; }
            public int ImportantProperty2 { get; set; }
            public int ImportantProperty3 { get; set; }
            public int ImportantProperty4 { get; set; }
            public int NonImportantProperty { get; set; }
    
            public bool Equals(MyClass other)
            {
                if (Object.ReferenceEquals(this, other))
                    return true;    
    
                return
                    (!Object.ReferenceEquals(this, null)) &&
                    (this.ImportantProperty1 == other.ImportantProperty1) &&
                    (this.ImportantProperty2 == other.ImportantProperty2) &&
                    (this.ImportantProperty3 == other.ImportantProperty3) &&
                    (this.ImportantProperty4 == other.ImportantProperty4);
            }
    
            public override bool Equals(object obj)
            {
                return this.Equals(obj as MyClass);
            }
    
            public override int GetHashCode()
            {
                unchecked {
                    int hash = 17;
                    hash = hash * 23 + ImportantProperty1.GetHashCode();
                    hash = hash * 23 + ImportantProperty2.GetHashCode();
                    hash = hash * 23 + ImportantProperty3.GetHashCode();
                    hash = hash * 23 + ImportantProperty4.GetHashCode();
                    return hash;
                }
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                MyClass a = new MyClass() { };
                MyClass b = new MyClass() { };
                if (a.Equals(b))
                    Console.WriteLine("a and b are equal");
            }
        }
    }
    
    名称空间值相等
    {
    类MyClass:IEquatable
    {
    public int ImportantProperty1{get;set;}
    public int ImportantProperty2{get;set;}
    public int ImportantProperty3{get;set;}
    public int ImportantProperty4{get;set;}
    公共int非重要属性{get;set;}
    公共布尔等于(MyClass其他)
    {
    if(Object.ReferenceEquals(this,other))
    返回true;
    返回
    (!Object.ReferenceEquals(this,null))&&
    (this.ImportantProperty1==其他.ImportantProperty1)&&
    (this.ImportantProperty2==其他.ImportantProperty2)&&
    (this.ImportantProperty3==其他.ImportantProperty3)&&
    (this.ImportantProperty4==其他.ImportantProperty4);
    }
    公共覆盖布尔等于(对象对象对象)
    {
    返回此.Equals(obj作为MyClass);
    }
    公共覆盖int GetHashCode()
    {
    未经检查{
    int hash=17;
    hash=hash*23+ImportantProperty1.GetHashCode();
    hash=hash*23+ImportantProperty2.GetHashCode();
    hash=hash*23+ImportantProperty3.GetHashCode();
    hash=hash*23+ImportantProperty4.GetHashCode();
    返回散列;
    }
    }
    }
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    MyClass a=新的MyClass(){};
    MyClass b=新的MyClass(){};
    如果(a等于(b))
    控制台。写线(“a和b相等”);
    }
    }
    }
    
    创建对象的层次结构,比较的唯一目的是避免过度使用。如果它们共享一些其他行为/实现的共性,那么这可能是合理的,否则我只需实现一个静态方法(扩展与否,并不重要),它只返回一个bool,指示两个给定实例的所有8个属性是否相同。它认为我忽略了最明显的解决方案!您也想看看我的一些变量名!;)
    namespace ValueEquality
    {
    
        class MyClass : IEquatable<MyClass>
        {
            public int ImportantProperty1 { get; set; }
            public int ImportantProperty2 { get; set; }
            public int ImportantProperty3 { get; set; }
            public int ImportantProperty4 { get; set; }
            public int NonImportantProperty { get; set; }
    
            public bool Equals(MyClass other)
            {
                if (Object.ReferenceEquals(this, other))
                    return true;    
    
                return
                    (!Object.ReferenceEquals(this, null)) &&
                    (this.ImportantProperty1 == other.ImportantProperty1) &&
                    (this.ImportantProperty2 == other.ImportantProperty2) &&
                    (this.ImportantProperty3 == other.ImportantProperty3) &&
                    (this.ImportantProperty4 == other.ImportantProperty4);
            }
    
            public override bool Equals(object obj)
            {
                return this.Equals(obj as MyClass);
            }
    
            public override int GetHashCode()
            {
                unchecked {
                    int hash = 17;
                    hash = hash * 23 + ImportantProperty1.GetHashCode();
                    hash = hash * 23 + ImportantProperty2.GetHashCode();
                    hash = hash * 23 + ImportantProperty3.GetHashCode();
                    hash = hash * 23 + ImportantProperty4.GetHashCode();
                    return hash;
                }
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                MyClass a = new MyClass() { };
                MyClass b = new MyClass() { };
                if (a.Equals(b))
                    Console.WriteLine("a and b are equal");
            }
        }
    }