第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

.NET中如何深度判斷2個(gè)對(duì)象相等

標(biāo)簽:
C#

5c1e70c00001d94909000580.jpg

背景

最近在群里,有人问如何深度比较2个对象相等,感觉很有意思,就自己研究了一下,并写了一个开源的小类库,地址如下https://github.com/lamondlu/ObjectEquality。

如果想直接使用这个类库,可以使用Nuget进行安装

CopyInstall-Package ObjectEquality

对象比较有几种情况

  1. 对象是值类型或者String,这里仅需要判断值是否相等

  2. 对象是Struct,需要判断Struct的每个字段是否一致

  3. 对象是集合,需要判断对应位置的对象是否相等

  4. 对象是数组,需要判断对应位置的对象是否相等

  5. 对象是Class, 需要判断Class的每个字段是否一致

这里可能有缺漏,大家可以帮我补充。

编写代码

这里我首先创建了一个IEquality接口,在其中定义了一个IsEqual方法,这个方法就是判断2个对象是否一致的方法。后面我会针对上面说明的几种对比场景,分别创建对应的实现类。

Copy    public interface IEquality
    {
        Func<object, bool> MatchCondition { get; }        bool IsEqual(object source, object target);
    }

这里MatchCondition是一个委托,它定义了当前对比类的匹配条件。

第二步,我们针对上述的几种对比场景,创建对应的实现类

值类型相等判断实现类

Copy    internal class ValueTypeEquality : IEquality
    {        public Func<object, bool> MatchCondition
        {            get
            {                return p => p.GetType().IsValueType || p.GetType() == typeof(string);
            }
        }        public bool IsEqual(object source, object target)        {            return source.Equals(target);
        }
    }

值类型的判断比较简单,直接调用Object类的Equals方法即可。

String类型虽然不是值类型,但是这里我们需要把它归到值类型中。

Struct相等判断实现类

Copy    internal class StructEquality : IEquality
    {        public Func<object, bool> MatchCondition
        {            get
            {                return p => p.GetType().IsValueType 
                    && !p.GetType().IsPrimitive 
                    && !p.GetType().IsEnum;
            }
        }        public bool IsEqual(object source, object target)        {            var type = source.GetType();            foreach (var prop in type.GetProperties())
            {                var equality = EqualityCollection.Equalities
                    .First(p => p.MatchCondition(prop.GetValue(source)));                var result = equality.IsEqual(prop.GetValue(source),
                    prop.GetValue(target));                if (!result)
                {                    return false;
                }
            }            return true;
        }
    }

这里我们读取了Struct中的每个属性,分别进行判断,如果有一个判断失败,即认为2个Struct对象不相等。

这里EqualityCollection是判断器集合,后续会添加这个类的代码。

集合相等判断实现类

Copy    internal class GenericCollectionEquality : IEquality
    {        public Func<object, bool> MatchCondition
        {            get
            {                return p => p.GetType().IsGenericType;
            }
        }        public bool IsEqual(object source, object target)        {            var type = source.GetType();            var genericType = type.GetGenericArguments()[0];            var genericCollectionType = typeof(IEnumerable<>).MakeGenericType(genericType);            if (type.GetInterfaces().Any(p => p == genericCollectionType))
            {                var countMethod = type.GetMethod("get_Count");                var sourceCount = (int)countMethod.Invoke(source, null);                var targetCount = (int)countMethod.Invoke(target, null);                if (sourceCount != targetCount)
                {                    return false;
                }                var sourceCollection = (source as IEnumerable<object>).ToList();                var targetCollection = (target as IEnumerable<object>).ToList();                for (var i = 0; i < sourceCount; i++)
                {                    var equality = EqualityCollection.Equalities.First(p => p.MatchCondition(sourceCollection[i]));                    var result = equality.IsEqual(sourceCollection[i], targetCollection[i]);                    if (!result)
                    {                        return false;
                    }
                }
            }            return true;
        }
    }

这里我们首先判断了集合的元素的数量是否一致,如果不一致,即这2个集合不相等。如果一致,我们继续判断对应位置的每个元素是否一致,如果全部都一直,则2个集合相当,否则2个集合不相等。

数组相等判断实现类

Copy    internal class ArrayEquality : IEquality
    {        public Func<object, bool> MatchCondition
        {            get
            {                return p => p.GetType().IsArray;
            }
        }        public bool IsEqual(object source, object target)        {
            Array s = source as Array;
            Array t = target as Array;            if (s.Length != t.Length)
            {                return false;
            }            
            for (var i = 0; i < s.Length; i++)
            {                var equality = EqualityCollection.Equalities
                    .First(p => p.MatchCondition(s.GetValue(i)));                var result = equality.IsEqual(s.GetValue(i), t.GetValue(i));                if (!result)
                {                    return false;
                }
            }            return true;
        }
    }

数组相等的判断类似集合,我们首先判断数组的长度是否一致,然后判断对应位置的元素是否一致。

类判断相等实现类

Copy    internal class ClassEquality : IEquality
    {        public Func<object, bool> MatchCondition
        {            get
            {                return p => p.GetType().IsClass;
            }
        }        public bool IsEqual(object source, object target)        {            var type = source.GetType();            foreach (var prop in type.GetProperties())
            {                var equality = EqualityCollection.Equalities
                    .First(p => p.MatchCondition(prop.GetValue(source)));                var result = equality.IsEqual(prop.GetValue(source), prop.GetValue(target));                if (!result)
                {                    return false;
                }
            }            return true;
        }
    }

添加判断相等实现类集合

Copy    public static class EqualityCollection
    {        public static readonly List<IEquality> Equalities = new List<IEquality> {            new StructEquality(),            new ValueTypeEquality(),            new ArrayEquality(),            new GenericCollectionEquality(),            new ClassEquality()
        };
    }

这里我们定义了一个静态类,来存储程序中使用的所有判断器。

这里在判断器集合中,实现类的其实是有顺序的,StructEquality必须要放到ValueTypeEquality的前面,因为Struct也是值类型,如果不放到最前面,会导致判断失败。

创建判断器入口类

Copy    public class ObjectEquality
    {        public bool IsEqual(object source, object target)        {            if (source.GetType() != target.GetType())
            {                return false;
            }            if (source == null && target == null)
            {                return true;
            }            else if (source == null && target != null)
            {                return false;
            }            else if (source != null && target == null)
            {                return false;
            }            var equality = EqualityCollection.Equalities
                .First(p => p.MatchCondition(source));            return equality.IsEqual(source, target);
        }
    }

前面所有实现类的访问级别都是Internal, 所以我们需要创建一个判断器入口类, 外部只能通过ObjectEquality类的实例来实现判断相等。

最终效果

下面我列举几个测试用例,看看效果是不是我们想要的

对比Struct

Copy    public struct DemoStruct
    {        public int Id { get; set; }        public string Name { get; set; }
    }
Copy    var a = new DemoStruct();
    a.Id = 1;
    a.Name = "Test";    var b = new DemoStruct();
    b.Id = 1;
    b.Name = "Test";    
    var c = new DemoStruct();
    b.Id = 2;
    b.Name = "Test";
    
    ObjectEquality objectEquality = new ObjectEquality();
    objectEquality.IsEqual(a,b); //true
    objectEquality.IsEqual(a,c); //false

对比类

Copy    public class SimpleClass
    {        public int Id { get; set; }        public string Name { get; set; }
    }
Copy    var a = new SimpleClass
    {
        Id = 1,
        Name = "A"
    };    var b = new SimpleClass
    {
        Id = 1,
        Name = "A"
    };    
    var c = new SimpleClass
    {
        Id = 2,
        Name = "A"
    };
    
    ObjectEquality objectEquality = new ObjectEquality();
    objectEquality.IsEqual(a,b); //true
    objectEquality.IsEqual(a,c); //false

对比数组

Copy    var a = new int[] { 1, 2, 3 };    var b = new int[] { 1, 2, 3 };    var c = new int[] { 1, 1, 2 }; 
    
    ObjectEquality objectEquality = new ObjectEquality();
    objectEquality.IsEqual(a,b); //true
    objectEquality.IsEqual(a,c); //false

作者:Lamond Lu

出处:https://www.cnblogs.com/lwqlun/p/10159770.html


點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫(xiě)下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專(zhuān)欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消