.net Distinct 去重问题分析

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

model1:

1  public class TestModel1
2     {
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 model1s
114                            select new TestModel1
115                                {
116                                    Id = m.Id,
117                                    Name = m.Name,
118                                    Address = m.Address
119                                }).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 model1s
230                            select new 
231                            {
232                                Id = m.Id,
233                                Name = m.Name,
234                                Address = m.Address
235                            }).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:下载

.net Distinct 去重问题分析,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。