gpt4 book ai didi

c# - 比较对象的方法

转载 作者:太空宇宙 更新时间:2023-11-03 12:56:19 25 4
gpt4 key购买 nike

我正在开发一种方法,可以传入 2 个相同类型的对象,并将比较这两个对象。最后,我计划重载它以接受属性名称等以仅评估那些或仅排除那些形成评估的。这必须在我完成基本的完整比较工作后才能发生。

我已经能够比较值类型和引用类型。我卡住的地方是能够比较可枚举的属性。 else 语句是我无法正常工作的内容。

public static void CompareObjects<T>(T obj1, T obj2)
{
foreach (var property in typeof(T).GetProperties())
{
var obj1Prop = property.GetValue(obj1);
var obj2Prop = property.GetValue(obj2);

//for value types
if (property.PropertyType.IsPrimitive || property.PropertyType.IsValueType || property.PropertyType == typeof(string))
{
if (obj1Prop != obj2Prop)
Console.WriteLine($"Object 1 {property.Name}:{obj1Prop}{Environment.NewLine}Object 2 {property.Name}:{obj2Prop}{Environment.NewLine}");
}
//for objects
else if (property.PropertyType.IsClass && !typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
dynamic obj1PropObj = Convert.ChangeType(obj1Prop, property.PropertyType);
dynamic obj2PropObj = Convert.ChangeType(obj2Prop, property.PropertyType);
CompareObjects(obj1PropObj, obj2PropObj);
}
//for Enumerables
else
{
var enumerablePropObj1 = property.GetValue(obj1) as IEnumerable;
var enumerablePropObj2 = property.GetValue(obj2) as IEnumerable;

if (enumerablePropObj1 == null) continue;
if (enumerablePropObj2 == null) continue;

var list1 = enumerablePropObj1.GetEnumerator();
var list2 = enumerablePropObj2.GetEnumerator();

while (list1.MoveNext())
{
list2.MoveNext();
CompareObjects(list1.Current, list2.Current);
}
}
}
}

这遍历列表但没有值。我用来实现它的设置如下:

static void Main(string[] args)
{
var student1 = new Student
{
FirstName = "John",
LastName = "Smith",
Age = 18,
DateOfBirth = DateTime.Parse("1989/03/03"),
Job = new Job
{
Company = "CompanyOne",
Title = "Supervisor"
},
PhoneNumbers = new List<PhoneNumber>
{
new PhoneNumber
{
Number = "8675309",
Label = "Home"
},
new PhoneNumber
{
Number = "1234567",
Label = "Work"
}
}
};
var student2 = new Student
{
FirstName = "Theodore",
LastName = "Smith",
Age = 22,
DateOfBirth = DateTime.Parse("1990/03/03"),
Job = new Job
{
Company = "CompanyOne",
Title = "Manager"
},
PhoneNumbers = new List<PhoneNumber>
{
new PhoneNumber
{
Number = "8675308",
Label = "Home"
},
new PhoneNumber
{
Number = "1234567",
Label = "Work"
}
}
};

CompareObjects(student1, student2);
Console.WriteLine("Done");

Console.ReadKey();
}

最佳答案

你的问题是你的方法是通用的。当您在子集合上调用它时,您用于比较的类型是 System.Object,当然没有可比较的有趣属性。

更改您的方法声明和方法的序言:

public static void CompareObjects(object obj1, object obj2)
{
if (obj1.GetType() != obj2.GetType())
{
return;
}

foreach (var property in obj1.GetType().GetProperties())
{
...

请注意,使用这种方法,您也不需要 dynamicChangeType() 代码。

最后,您可能需要考虑更改不等式比较,以便使用 Equals() 方法代替 != 运算符:

        if (!obj1Prop.Equals(obj2Prop))
{
Console.WriteLine($"Object 1 {property.Name}:{obj1Prop}{Environment.NewLine}Object 2 {property.Name}:{obj2Prop}{Environment.NewLine}");
}

即使方法是通用的,那也是个好主意;虽然如果重写 Equals()应该 实现相等和不等运算符,但这并不总是会发生。当该方法是非泛型时,您当然甚至不会获得特定类型的运算符重载(至少在没有大量额外工作的情况下不会)。


(我想您可以使用与上述相同的 dynamic/ChangeType() 方法来代替不可枚举的属性,例如使用 list1 .Current.GetType() 作为类型而不是 property.PropertyType;这可以让该方法保持通用。但是 dynamic 有很多额外的开销最终它会全部归结为执行相同的代码,我只是不明白这样做的意义。)

关于c# - 比较对象的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33700377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com