首页 > 代码库 > .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:下载
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。