C# 变量的相等性检验

C# 变量的相等性检验,c#,.net,C#,.net,我正在做一个用C#和.NET4.0编写的项目 有一个函数可以比较两个对象的某些属性。两个对象的类型相同。考虑下面的类: class A { public UInt32 Prop1 {get; set;} public byte Prop2 {get; set;} public string Prop3 {get; set;} public int[] Prop4 {get; set;} } 在我的比较函数中,我使用反射遍历每个属性,并获取属性值: var val

我正在做一个用C#和.NET4.0编写的项目

有一个函数可以比较两个对象的某些属性。两个对象的类型相同。考虑下面的类:

class A
{
    public UInt32 Prop1 {get; set;}
    public byte Prop2 {get; set;}
    public string Prop3 {get; set;}
    public int[] Prop4 {get; set;}
}
在我的比较函数中,我使用反射遍历每个属性,并获取属性值:

var value1 = t1.GetType().GetProperty(cp.ToString()).GetValue(t1, null);
var value2 = t2.GetType().GetProperty(cp.ToString()).GetValue(t2, null);
enum Properties
{ Prop1, Prop2, Prop3, Prop4 }
其中
t1
t2
都属于
A
类型,
cp
是属性的
enum

var value1 = t1.GetType().GetProperty(cp.ToString()).GetValue(t1, null);
var value2 = t2.GetType().GetProperty(cp.ToString()).GetValue(t2, null);
enum Properties
{ Prop1, Prop2, Prop3, Prop4 }
接下来我要做的是平等测试:

if (!value1.Equals(value2))
{
    // Handle differences
}
测试返回数组的
Prop4
时,
Equals()
始终返回false,即使数组大小和内容相同


检测返回类型是否可枚举,然后对可枚举的单个元素执行相等性测试的最简单方法是什么?

您可以使用
type.IsAssignableFrom()
方法:

if(typeof(IEnumerable).IsAssignableFrom(t2.GetType()))
{

}
我不能100%确定使用您的技术想要实现什么,但是使用带有附加
enum
的反射来获取属性值似乎是一个糟糕的设计决策

更新

如果您拥有类代码,那么您应该实现并比较其中的所有属性

class A : IEquatable<A>
{
    public UInt32 Prop1 { get; set; }
    public byte Prop2 { get; set; }
    public string Prop3 { get; set; }
    public int[] Prop4 { get; set; }

    public bool Equals(A other)
    {
        return other != null
            && Prop1 == other.Prop1
            && Prop2 == other.Prop2
            && Prop3 == other.Prop3
            && System.Linq.Enumerable.SequenceEqual(Prop4, other.Prop4);
    }
}
A类:可满足
{
公共UInt32 Prop1{get;set;}
公共字节Prop2{get;set;}
公共字符串Prop3{get;set;}
公共int[]Prop4{get;set;}
公共布尔等于(其他)
{
返回其他!=null
&&Prop1==其他。Prop1
&&Prop2==其他。Prop2
&&Prop3==其他。Prop3
&&System.Linq.Enumerable.SequenceEqual(Prop4,other.Prop4);
}
}

您可以使用
Type.IsAssignableFrom()
方法:

if(typeof(IEnumerable).IsAssignableFrom(t2.GetType()))
{

}
我不能100%确定使用您的技术想要实现什么,但是使用带有附加
enum
的反射来获取属性值似乎是一个糟糕的设计决策

更新

如果您拥有类代码,那么您应该实现并比较其中的所有属性

class A : IEquatable<A>
{
    public UInt32 Prop1 { get; set; }
    public byte Prop2 { get; set; }
    public string Prop3 { get; set; }
    public int[] Prop4 { get; set; }

    public bool Equals(A other)
    {
        return other != null
            && Prop1 == other.Prop1
            && Prop2 == other.Prop2
            && Prop3 == other.Prop3
            && System.Linq.Enumerable.SequenceEqual(Prop4, other.Prop4);
    }
}
A类:可满足
{
公共UInt32 Prop1{get;set;}
公共字节Prop2{get;set;}
公共字符串Prop3{get;set;}
公共int[]Prop4{get;set;}
公共布尔等于(其他)
{
返回其他!=null
&&Prop1==其他。Prop1
&&Prop2==其他。Prop2
&&Prop3==其他。Prop3
&&System.Linq.Enumerable.SequenceEqual(Prop4,other.Prop4);
}
}

您可以使用
Type.IsAssignableFrom()
方法:

if(typeof(IEnumerable).IsAssignableFrom(t2.GetType()))
{

}
我不能100%确定使用您的技术想要实现什么,但是使用带有附加
enum
的反射来获取属性值似乎是一个糟糕的设计决策

更新

如果您拥有类代码,那么您应该实现并比较其中的所有属性

class A : IEquatable<A>
{
    public UInt32 Prop1 { get; set; }
    public byte Prop2 { get; set; }
    public string Prop3 { get; set; }
    public int[] Prop4 { get; set; }

    public bool Equals(A other)
    {
        return other != null
            && Prop1 == other.Prop1
            && Prop2 == other.Prop2
            && Prop3 == other.Prop3
            && System.Linq.Enumerable.SequenceEqual(Prop4, other.Prop4);
    }
}
A类:可满足
{
公共UInt32 Prop1{get;set;}
公共字节Prop2{get;set;}
公共字符串Prop3{get;set;}
公共int[]Prop4{get;set;}
公共布尔等于(其他)
{
返回其他!=null
&&Prop1==其他。Prop1
&&Prop2==其他。Prop2
&&Prop3==其他。Prop3
&&System.Linq.Enumerable.SequenceEqual(Prop4,other.Prop4);
}
}

您可以使用
Type.IsAssignableFrom()
方法:

if(typeof(IEnumerable).IsAssignableFrom(t2.GetType()))
{

}
我不能100%确定使用您的技术想要实现什么,但是使用带有附加
enum
的反射来获取属性值似乎是一个糟糕的设计决策

更新

如果您拥有类代码,那么您应该实现并比较其中的所有属性

class A : IEquatable<A>
{
    public UInt32 Prop1 { get; set; }
    public byte Prop2 { get; set; }
    public string Prop3 { get; set; }
    public int[] Prop4 { get; set; }

    public bool Equals(A other)
    {
        return other != null
            && Prop1 == other.Prop1
            && Prop2 == other.Prop2
            && Prop3 == other.Prop3
            && System.Linq.Enumerable.SequenceEqual(Prop4, other.Prop4);
    }
}
A类:可满足
{
公共UInt32 Prop1{get;set;}
公共字节Prop2{get;set;}
公共字符串Prop3{get;set;}
公共int[]Prop4{get;set;}
公共布尔等于(其他)
{
返回其他!=null
&&Prop1==其他。Prop1
&&Prop2==其他。Prop2
&&Prop3==其他。Prop3
&&System.Linq.Enumerable.SequenceEqual(Prop4,other.Prop4);
}
}


我也同意Marcin关于使用反射来获取属性值的观点,但是,再一次,我不确定最终目标是什么。我也不喜欢这个设计,但我还没有找到更好的方法。我必须为相同类型的两个对象实现比较函数。这并不是完全的成员比较。相反,只需要比较固定的属性子集。例如,一个类有40个属性,其中25个属性将用于相等比较。这是要求。有没有更好的设计方法?C#不是我的主要语言。@MarcinJuraszek:是的。@Donotalo你说你拥有这些课程。为什么不直接编写代码,例如实现
IEquatable
接口?如果不使用反射就可以达到同样的效果,那么使用反射似乎是不对的,也不会像标准代码那样快。@MarcinJuraszek:谢谢您的帮助。我以后再看。:)一、 我也同意Marcin关于使用反射来获取属性值的观点,但是,再一次,我不确定最终目标是什么。我也不喜欢这个设计,但我还没有找到更好的方法。我必须为相同类型的两个对象实现比较函数。这并不是完全的成员比较。相反,只需要比较固定的属性子集。例如,一个类有40个属性,其中25个属性将用于相等比较。这是要求。有没有更好的设计方法?C#不是我的主要语言。@MarcinJuraszek:是的。@Donotalo你说你拥有这些课程。为什么不直接编写代码,例如实现
IEquatable
接口?如果不使用反射就可以达到同样的效果,那么使用反射似乎是不对的,也不会像标准代码那样快。@MarcinJuraszek:谢谢您的帮助。我待会再看。