700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 26复杂类型比较 使用Compare .NET objects组件

26复杂类型比较 使用Compare .NET objects组件

时间:2020-03-21 09:25:41

相关推荐

26复杂类型比较 使用Compare .NET objects组件

关于比较对象,在"06判等对象是否相等"中大致可以总结为:

关于比较方法:

● 实例方法Equals(object obj)既可以比较值类型,也可以比较引用类型

● 静态方法Equals(object objA, object objB),比较值类型

● 静态方法ReferenceEquals(object objA, object objB),比较引用类型

● 比较引用类型可以用==,比较值类型不能用==

关于比较原则:

● 值类型比较的是值

● 引用类型比较的是引用地址

对于复杂类型,无论是复杂值类型(比如结构)还是复杂引用类型(包含值类型成员),经常要重写System.Object中的虚方法Equals(object obj)。比如,针对复杂值类型,可能这样重写:

public override bool Equals(object obj)

{

if (obj == null)

{

return false;

}

RuntimeType type = (RuntimeType) base.GetType();

RuntimeType type2 = (RuntimeType) obj.GetType();

if (type2 != type) //比较两个对象是否是同一类型

{

return false;

}

object a = this;

if (CanCompareBits(this)) //对象成员如果存在对于堆的引用返回false

{

return FastEqualsCheck(a, obj);

}

//反射获取值类型的所有字段

FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

for (int i = 0; i < fields.Length; i++) //遍历字段,对各个字段进行比较

{

object obj3 = ((RtFieldInfo) fields[i]).UnsafeGetValue(a);

object obj4 = ((RtFieldInfo) fields[i]).UnsafeGetValue(obj);

if (obj3 == null)

{

if (obj4 != null)

{

return false;

}

}

else if (!obj3.Equals(obj4))

{

return false;

}

}

return true;

}

而现在,在NuGet上输入"Compare .NET objects",可以获取到该组件,对任何.NET对象进行比较、列出各个属性的值甚至自定义比较规则。

比较复杂类型:包含值类型成员

public class Teacher

{

public int Id { get; set; }

public string Name { get; set; }

public DateTime JoinTime { get; set; }

public TeacherClass TeacherClass { get; set; }

}

public enum TeacherClass

{

[Description("执教5年以上")]

FirstClass = 0,

[Description("执教3年以上")]

SecondClass,

[Description("执教1年以上")]

ThirdClass

}

主程序:

Teacher teacher1 = new Teacher(){Id=1,JoinTime = new DateTime(,1,1),Name = "张老师",TeacherClass = TeacherClass.FirstClass};

Teacher teacher2 = new Teacher() { Id = 2, JoinTime = new DateTime(, 1, 2), Name = "李老师", TeacherClass = TeacherClass.SecondClass };

//获取Teacher属性的个数

int propertyCount = typeof (Teacher).GetProperties().Length;

//创建比较规则

CompareLogic compareLogic = new CompareLogic()

{

Config = new ComparisonConfig()

{

MaxDifferences = propertyCount//MaxDifferences的默认值是1

}

};

bool result = pare(teacher1, teacher2).AreEqual;

Console.Write(result);

Console.ReadKey();

结果:false

比较复杂类型,并列出2个比较对象所有属性的值

Teacher teacher1 = new Teacher(){Id=1,JoinTime = new DateTime(,1,1),Name = "张老师",TeacherClass = TeacherClass.FirstClass};

Teacher teacher2 = new Teacher() { Id = 2, JoinTime = new DateTime(, 1, 2), Name = "李老师", TeacherClass = TeacherClass.SecondClass };

//获取Teacher属性的个数

int propertyCount = typeof (Teacher).GetProperties().Length;

//创建比较规则

CompareLogic compareLogic = new CompareLogic()

{

Config = new ComparisonConfig()

{

MaxDifferences = propertyCount//MaxDifferences的默认值是1

}

};

//获取2个比较对象的不同之处

List<Difference> differences = pare(teacher1, teacher2).Differences;

StringBuilder sb = new StringBuilder();

foreach (Difference diff in differences)

{

sb.AppendLine("属性名称:" + diff.PropertyName);

sb.AppendLine("第一个对象值:" + diff.Object1Value);

sb.AppendLine("第二个对象值:" + diff.Object2Value + "\r\n");

}

using (StreamWriter outfile = new StreamWriter(@"F:\CompareObjects.txt"))

{

outfile.Write(sb.ToString());

}

}

结果:

比较复杂类型,并列出2个比较对象所有属性的值,对枚举属性自定义比较规则

需要一个自定义类,继承"Compare .NET objects"的BaseTypeComparer类,把打在枚举成员上的描述特性信息输出。

重写方法IsTypeMatch()用于判断2个比较对象的属性是否是枚举,如果是枚举,就采用重写方法CompareType()所定义的关于枚举属性的比较规则。

public class CustomEnumComparer : BaseTypeComparer

{

public CustomEnumComparer() : base(RootComparerFactory.GetRootComparer()){}

public override void CompareType(ComparisonResult result, object object1, object object2, string breadCrumb)

{

if (object1.ToString() != object2.ToString())

{

Difference difference = new Difference()

{

PropertyName = breadCrumb,

Object1Value = EnumHelper.GetDescription(object1),

Object2Value = EnumHelper.GetDescription(object2),

Object1 = new WeakReference(object1), //弱对象引用,即使被引用也可被垃圾回收

Object2 = new WeakReference(object2)

};

AddDifference(result,difference);

}

}

public override bool IsTypeMatch(Type type1, Type type2)

{

return TypeHelper.IsEnum(type1) && TypeHelper.IsEnum(type2);

}

}

//获取枚举类型的描述特性

public static class EnumHelper

{

public static string GetDescription(object enumMember)

{

//获取枚举类型的字段信息

FieldInfo fi = enumMember.GetType().GetField(enumMember.ToString());

//获取字段上的描述特性

IEnumerable<DescriptionAttribute> attributes = fi.GetCustomAttributes<DescriptionAttribute>(false);

return attributes.Any() ? attributes.ElementAt(0).Description : enumMember.ToString();

}

}

只需要把针对枚举属性的自定义类赋值给CompareLogic实例即可:

Teacher teacher1 = new Teacher(){Id=1,JoinTime = new DateTime(,1,1),Name = "张老师",TeacherClass = TeacherClass.FirstClass};

Teacher teacher2 = new Teacher() { Id = 2, JoinTime = new DateTime(, 1, 2), Name = "李老师", TeacherClass = TeacherClass.SecondClass };

//获取Teacher属性的个数

int propertyCount = typeof (Teacher).GetProperties().Length;

//创建比较规则

CompareLogic compareLogic = new CompareLogic()

{

Config = new ComparisonConfig()

{

MaxDifferences = propertyCount,//MaxDifferences的默认值是1

CustomComparers = new List<BaseTypeComparer>(){new CustomEnumComparer()}

}

};

//bool result = pare(teacher1, teacher2).AreEqual;

//Console.Write(result);

//Console.ReadKey();

//获取2个比较对象的不同之处

List<Difference> differences = pare(teacher1, teacher2).Differences;

StringBuilder sb = new StringBuilder();

foreach (Difference diff in differences)

{

sb.AppendLine("属性名称:" + diff.PropertyName);

sb.AppendLine("第一个对象值:" + diff.Object1Value);

sb.AppendLine("第二个对象值:" + diff.Object2Value + "\r\n");

}

using (StreamWriter outfile = new StreamWriter(@"F:\CompareObjects.txt"))

{

outfile.Write(sb.ToString());

}

结果:

参考资料:

Compare .NET Objects Tutorial

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。