首页 > 代码库 > .net Distinct 去重问题分析

.net Distinct 去重问题分析

问题:.net中的distinct方法对于自定义的类(class model )去重时失效。问题分析:

model1:

1  public class TestModel12     {3         public int Id { get; set; }4         public string Name { get; set; }5         public string Address { get; set; }6     }

model2:

 public class TestModel2    {        protected bool Equals(TestModel2 other)        {            return Id == other.Id && string.Equals(Name, other.Name) && string.Equals(Address, other.Address);        }        public override int GetHashCode()        {            unchecked            {                int hashCode = Id;                hashCode = (hashCode*397) ^ (Name != null ? Name.GetHashCode() : 0);                hashCode = (hashCode*397) ^ (Address != null ? Address.GetHashCode() : 0);                return hashCode;            }        }        public int Id { get; set; }        public string Name { get; set; }        public string Address { get; set; }        public override bool Equals(object obj)        {            if (ReferenceEquals(null, obj)) return false;            if (ReferenceEquals(this, obj)) return true;            if (obj.GetType() != this.GetType()) return false;            return Equals((TestModel2) obj);        }    }

Model3:

 public class TestModel3    {        public int Id { get; set; }        public string Name { get; set; }        public string Address { get; set; }            }    public class ListTestModel3 : IEqualityComparer<TestModel3>    {        public bool Equals(TestModel3 x, TestModel3 y)        {            if (x.Id == y.Id && x.Name == y.Name && x.Address == y.Address)            {                return true;            }            return false;        }        public int GetHashCode(TestModel3 obj)        {            return 0;        }    }

主程序:

  1   public partial class Form1 : Form  2     {  3         public Form1()  4         {  5             InitializeComponent();  6             InitData();  7   8         }  9  10         private void InitData() 11         { 12  13             var model1s = new List<TestModel1>(); 14             var model2s = new List<TestModel2>(); 15             var model3s = new List<TestModel3>(); 16             for (int i = 0; i < 3; i++) 17             { 18                 var model1 = new TestModel1() 19                     { 20                         Id = 10001, 21                         Name = "张三", 22                         Address = "中国-上海" 23                     }; 24                 var model2 = new TestModel2() 25                     { 26                         Id = 10001, 27                         Name = "张三", 28                         Address = "中国-上海" 29                     }; 30                 var model3 = new TestModel3() 31                     { 32                         Id = 10001, 33                         Name = "张三", 34                         Address = "中国-上海" 35                     }; 36                 model1s.Add(model1); 37                 model2s.Add(model2); 38                 model3s.Add(model3); 39             } 40  41             for (int i = 0; i < 3; i++) 42             { 43                 var model1 = new TestModel1() 44                     { 45                         Id = 10002, 46                         Name = "张三", 47                         Address = "中国-上海" 48                     }; 49                 var model2 = new TestModel2() 50                     { 51                         Id = 10002, 52                         Name = "张三", 53                         Address = "中国-上海" 54                     }; 55                 var model3 = new TestModel3() 56                     { 57                         Id = 10002, 58                         Name = "张三", 59                         Address = "中国-上海" 60                     }; 61                 model1s.Add(model1); 62                 model2s.Add(model2); 63                 model3s.Add(model3); 64             } 65             for (int i = 0; i < 3; i++) 66             { 67                 var model1 = new TestModel1() 68                     { 69                         Id = 10001, 70                         Name = "李四", 71                         Address = "中国-上海" 72                     }; 73                 var model2 = new TestModel2() 74                     { 75                         Id = 10001, 76                         Name = "李四", 77                         Address = "中国-上海" 78                     }; 79                 var model3 = new TestModel3() 80                     { 81                         Id = 10001, 82                         Name = "李四", 83                         Address = "中国-上海" 84                     }; 85                 model1s.Add(model1); 86                 model2s.Add(model2); 87                 model3s.Add(model3); 88             } 89             for (int i = 0; i < 3; i++) 90             { 91                 var model1 = new TestModel1() 92                     { 93                         Id = 10002, 94                         Name = "李四", 95                         Address = "中国-上海" 96                     }; 97                 var model2 = new TestModel2() 98                     { 99                         Id = 10002,100                         Name = "李四",101                         Address = "中国-上海"102                     };103                 var model3 = new TestModel3()104                     {105                         Id = 10002,106                         Name = "李四",107                         Address = "中国-上海"108                     };109                 model1s.Add(model1);110                 model2s.Add(model2);111                 model3s.Add(model3);112             }113             var model4s = (from m in model1s114                            select new TestModel1115                                {116                                    Id = m.Id,117                                    Name = m.Name,118                                    Address = m.Address119                                }).ToList().Distinct();120             dataGridView1.DataSource = model1s;121             dataGridView2.DataSource = model2s;122             dataGridView3.DataSource = model3s;123             dataGridView4.DataSource = model4s.ToList(); ;124         }125 126         private void InitDistinctData()127         {128 129             var model1s = new List<TestModel1>();130             var model2s = new List<TestModel2>();131             var model3s = new List<TestModel3>();132             for (int i = 0; i < 3; i++)133             {134                 var model1 = new TestModel1()135                     {136                         Id = 10001,137                         Name = "张三",138                         Address = "中国-上海"139                     };140                 var model2 = new TestModel2()141                     {142                         Id = 10001,143                         Name = "张三",144                         Address = "中国-上海"145                     };146                 var model3 = new TestModel3()147                     {148                         Id = 10001,149                         Name = "张三",150                         Address = "中国-上海"151                     };152                 model1s.Add(model1);153                 model2s.Add(model2);154                 model3s.Add(model3);155             }156 157             for (int i = 0; i < 3; i++)158             {159                 var model1 = new TestModel1()160                     {161                         Id = 10002,162                         Name = "张三",163                         Address = "中国-上海"164                     };165                 var model2 = new TestModel2()166                     {167                         Id = 10002,168                         Name = "张三",169                         Address = "中国-上海"170                     };171                 var model3 = new TestModel3()172                     {173                         Id = 10002,174                         Name = "张三",175                         Address = "中国-上海"176                     };177                 model1s.Add(model1);178                 model2s.Add(model2);179                 model3s.Add(model3);180             }181             for (int i = 0; i < 3; i++)182             {183                 var model1 = new TestModel1()184                     {185                         Id = 10001,186                         Name = "李四",187                         Address = "中国-上海"188                     };189                 var model2 = new TestModel2()190                     {191                         Id = 10001,192                         Name = "李四",193                         Address = "中国-上海"194                     };195                 var model3 = new TestModel3()196                     {197                         Id = 10001,198                         Name = "李四",199                         Address = "中国-上海"200                     };201                 model1s.Add(model1);202                 model2s.Add(model2);203                 model3s.Add(model3);204             }205             for (int i = 0; i < 3; i++)206             {207                 var model1 = new TestModel1()208                     {209                         Id = 10002,210                         Name = "李四",211                         Address = "中国-上海"212                     };213                 var model2 = new TestModel2()214                     {215                         Id = 10002,216                         Name = "李四",217                         Address = "中国-上海"218                     };219                 var model3 = new TestModel3()220                     {221                         Id = 10002,222                         Name = "李四",223                         Address = "中国-上海"224                     };225                 model1s.Add(model1);226                 model2s.Add(model2);227                 model3s.Add(model3);228             }229             var model4s = (from m in model1s230                            select new 231                            {232                                Id = m.Id,233                                Name = m.Name,234                                Address = m.Address235                            }).ToList().Distinct();236             dataGridView1.DataSource = model1s.Distinct().ToList();237             dataGridView2.DataSource = model2s.Distinct().ToList();238             dataGridView3.DataSource = model3s.Distinct(new ListTestModel3()).ToList();239             dataGridView4.DataSource = model4s.ToList();240         }241 242         private void button1_Click(object sender, EventArgs e)243         {244             InitDistinctData();245 246         }

过滤前结果:

过滤后结果:

 

分析:model1不管过滤前和过滤后均没有去重,model2 重写了Equals 和GetHashCode两个方法,过滤前后结果不一样, model3实现了IEqualityComparer接口进行了Distinct时重写Equals 和GetHashCode两个方法。效果和model2是一样的。Model4,去重之前用的是自己定义的实体类,框架不知道相等的条件,顾虽然去重但是没有效果,过滤后Model4采用了匿名方法类,简单的匿名类型内部实际是键值对,框架内部使用默认的相等比较器对值进行比较,所以可以去重。

结论:自定义类无法实现多键值去重(Distinct),可以通过以上三种方法去实现。

 

Demo:下载