teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

ぬるり!ぬるり!

2016/12/21 09:02

投稿

tamoto
tamoto

スコア4344

answer CHANGED
@@ -55,7 +55,7 @@
55
55
  this.Name = name;
56
56
  }
57
57
 
58
- public bool Equals(Person obj) => this.Name == obj.Name;
58
+ public bool Equals(Person obj) => this.Name == obj?.Name;
59
59
 
60
60
  public override bool Equals(object obj) => this.Equals(obj as Person);
61
61
 

1

もう一つの解決法の提案

2016/12/21 09:02

投稿

tamoto
tamoto

スコア4344

answer CHANGED
@@ -3,6 +3,8 @@
3
3
  ExceptメソッドをIEqualityComparer<T>付きで使えば良いと思います。
4
4
  自分の場合は以下のように書きます。
5
5
 
6
+ ---
7
+
6
8
  こんな感じのユーティリティクラスを予め用意しておいて、
7
9
  ```csharp
8
10
 
@@ -34,4 +36,35 @@
34
36
  var diffList = local.Except(web, new LambdaEqualityComparer<Person>((x, y) => x.Name == y.Name, x => x.Name.GetHashCode()));
35
37
  ```
36
38
 
37
- どうですかね?
39
+ どうですかね?
40
+
41
+ ---
42
+
43
+ もう一つの方法として、既存のクラスに変更を加えることが可能なら、
44
+ PersonクラスにIEquatable<T>を実装し、object.Equals(object)とobject.GetHashCode()をオーバーライドすることで、Exceptの動作を意図したものにすることが可能です。
45
+
46
+ ```csharp
47
+ public class Person : IEquatable<Person>
48
+ {
49
+ public int Id { get; private set; }
50
+ public string Name { get; private set; }
51
+
52
+ public Person(int id, string name)
53
+ {
54
+ this.Id = id;
55
+ this.Name = name;
56
+ }
57
+
58
+ public bool Equals(Person obj) => this.Name == obj.Name;
59
+
60
+ public override bool Equals(object obj) => this.Equals(obj as Person);
61
+
62
+ public override int GetHashCode() => this.Name.GetHashCode();
63
+ }
64
+ ```
65
+
66
+ ```csharp
67
+ var diffList = local.Except(web);
68
+ ```
69
+
70
+ この場合、`Name`が同じである`Person`は本当に「同じモノである」として扱われることになるので、それによって何か不都合が生じないように注意する必要があります。