質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

2351閲覧

C# List<T> の要素比較

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2018/07/12 11:08

C#にてFormアプリを開発中です。

List<T>について二つのリストの要素が等しいかを判定する方法は無いでしょうか。

SequenceEqualだと参照比較になってしまい、実データの比較ができません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papinianus

2018/07/12 11:19

Tはどんな型ですか?自作Classですか?
退会済みユーザー

退会済みユーザー

2018/07/12 11:21

自作Classです。
退会済みユーザー

退会済みユーザー

2018/07/13 00:04

「二つのリストの要素」とはなんですか? なにと何を何の目的で比較するのですか? List<T> に Distinct を適用したいとか?
guest

回答2

0

こっちのオーバーロードを使ってIEqualityComparerを渡せばよいかと。

投稿2018/07/12 11:26

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2018/07/12 11:30

もしくは、自作クラス側でEqualsメソッドをオーバーライドするかですね。
papinianus

2018/07/12 12:08

おっしゃるとおりですね。 質問者様に伝えるという観点で言えば、SequenceEqualだから参照比較しかできないのではなく、T型のEqualsが参照比較になっていることが、やりたいことができない原因なので「IEquatableを実装する」が本筋のように思えます。 それができないような場合、あるいは一過的でそこまでしたくない場合などを考えると比較方法を渡すが選択肢にあがるのかなと。
退会済みユーザー

退会済みユーザー

2018/07/13 00:09

自作クラス毎にIEqualityComparerの派生クラス用意するのがなと思ったら 汎用的なクラスを作ってる方がいました。 https://qiita.com/s-matsuba/items/1ee6bcc1bc5d721fc978 ただ、いまいち使い方がわからないので教えて欲しいです。
papinianus

2018/07/13 14:13

自作クラスがどのようなものであるかにもよりますが、オブジェクト指向って基本的にクラスごとにIEqualityComparerとかIEquatableの実装とかをする思想だと思っています。 既に解決していますが、`public static bool ValueEquals(testclass x, testclass y)`は、やはりクラスごとに実装するわけですよね。 ジャストアイデアですが、そのPOCOは ・structにはできないか ・基底クラスでIEqutableかIEqualityComparerのデフォルト実装を持てないか(そういうデータにできないか) などもご検討くだされば良いのではないかと思います。
guest

0

ベストアンサー

コメントにあった汎用クラスの使用方法の簡単な例です。

C#

1 static void Main(string[] args) 2 { 3 4 5 List<testclass> List1 = new List<testclass>(); 6 List<testclass> List2 = new List<testclass>(); 7 8 testclass t; 9 10 t = new testclass(1,"ABC","123"); 11 List1.Add(t); 12 13 t = new testclass(2, "DEF","123"); 14 List1.Add(t); 15 16 t = new testclass(1, "ABC","456"); 17 List2.Add(t); 18 19 t = new testclass(2, "DEF","456"); 20 List2.Add(t); 21 22 GenericEqualityComparer<testclass> EqComp=new GenericEqualityComparer<testclass>(ValueEquals); 23 24 Console.WriteLine(string.Format("SequenceEqual = {0}", List1.SequenceEqual(List2))); 25 Console.WriteLine(string.Format("SequenceEqual(IEqualityComparer) = {0}", List1.SequenceEqual(List2,EqComp))); 26 27 Console.ReadKey(); 28 } 29 30 31 public static bool ValueEquals(testclass x, testclass y) 32 { 33 if ((x.Value_A == y.Value_A) && (x.Value_B == y.Value_B)) 34 { 35 return true; 36 } 37 else 38 { 39 return false; 40 } 41 } 42 } 43 44 45 public class testclass 46 { 47 48 public int Value_A; 49 public string Value_B; 50 public string Value_C; 51 52 public testclass(int valueA,string valueB,string valueC) 53 { 54 Value_A = valueA; 55 Value_B = valueB; 56 Value_C = valueC; 57 } 58 59 } 60 61 public class GenericEqualityComparer<T> : IEqualityComparer<T> 62 { 63 private Func<T, T, bool> _predicate; 64 private Func<T, int> _gethash; 65 66 public GenericEqualityComparer(Func<T, T, bool> predicate) 67 : this(predicate, obj => obj.GetHashCode()) 68 { 69 } 70 public GenericEqualityComparer(Func<T, T, bool> predicate, Func<T, int> gethash) 71 { 72 _predicate = predicate; 73 _gethash = gethash; 74 } 75 76 public bool Equals(T x, T y) 77 { 78 return _predicate(x, y); 79 } 80 public int GetHashCode(T obj) 81 { 82 return _gethash(obj); 83 } 84 } 85

比較部分を外だしして、指定できるような形になっています。
例ではHashCodeの比較部分は実装していませんが、そちらの関数も指定できるようになっています。

投稿2018/07/13 00:44

YAmaGNZ

総合スコア10222

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2018/07/13 01:15

こちらの回答はpapinianusさんの回答の派生というか、コメント欄では書きにくかった為に書いたものなので、ベストアンサーはpapinianusさんの回答のほうにつけていただいたほうがよいかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問