Rainbow Planet

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

C#

C#のIComparerの実装方法や用法について(サンプルプログラムあり)

投稿日:2021年2月1日 更新日:

<目次>

(1) C#のIComparerの実装方法や用法について
 (1-1) IComparerの概要
 (1-2) STEP0:比較をするクラスの定義
 (1-3) STEP1:IComparerインターフェイスの実装
 (1-4) STEP2:Compareメソッドの実装
 (1-5) STEP3:ソートの実行
 (1-6) サンプルプログラム

(1) C#のIComparerの実装方法や用法について

IComparerはオブジェクト同士の比較を行うためのメソッドを公開したインターフェイスです。

int型やdouble型などの基本データ型の比較はイメージが付きやすいが、複数のフィールドを持つクラスとなると、どのように比較するでしょうか?

結論として、オブジェクト同士の比較の場合は一致とみなす条件を自分たちで定義でき、それに合致するかどうかで、イコールかどうかを判断しています。

この記事ではIComparerの概要や使い方についてご紹介いたします。

(1-1) IComparerの概要

「IComparer」インターフェイスは主に「要素のソート」に利用されます。「2つのインスタンスの比較」を行う点は「IComparable」と似ていますが、異なる点として「IComparable」では出来ない「自身のコントロールが及ばない(=変更権限のないクラス)のインスタンス比較」にも対応する事ができます。

目次にもどる

(1-2) STEP0:比較をするクラスの定義

事前準備としてIComparerで比較したいクラスを定義します(この手順はIComparer特有のステップではないのですが、省略すると分かりにくいので書きます)。

下記例のBig4Players2クラスでは、男子テニスの「Big4」と呼ばれている4名の名前(Name)と、グランドスラム優勝回数(GrandSlamWin)を保持するための容器です。最終的にはint型の優勝回数の「降順」(大きい順)のソートを実現します。

(STEP0)

    class Big4Players2
    {
        // メンバ変数
        public string Name { get; set; }
        public int GrandSlamWin { get; set; }
        public override string ToString()
        {
            return $"{this.Name} {this.GrandSlamWin}";
        }
    }

(参考)
「{ get; set; }」は「プロパティ」と呼ばれ、メンバ変数のゲッター(取得)、セッター(更新)のメソッドを定義しています。

目次にもどる

(1-3) STEP1:IComparerインターフェイスの実装

まずはIComparerインターフェイスを実装したクラスを定義します。

(構文)
class [クラス名] : IComparer <[比較対象クラス名]>
{
	//クラスの定義
}


(STEP1)

// STEP1:IComparerインターフェイスの実装
class Big4Comparer : IComparer<Big4Players2>
{
        //クラスの実装
}

目次にもどる

(1-4) STEP2:Compareメソッドの実装

次にCompareメソッド「public int Compare(object x, object y)」を実装します。このメソッドは同じ型の2つのインスタンスを比較し、その大小をint型で返却します。戻り値の値はソートを昇順でしたいのか?降順でしたいのか?によって次のように定義します。

(1)昇順にソートする場合「自身の方が大きい=1、自身の方が小さい=-1、同じ=0」
(2)降順にソートする場合「自身の方が大きい=-1、自身の方が小さい=1、同じ=0」
 

(STEP2)

    class Big4Comparer : IComparer<Big4Players2>
    {
        // STEP2:Compareメソッドの実装
        public int Compare(Big4Players2 x, Big4Players2 y)
        {
            // 降順にソートしたいので、x < y に1を割り当て
            if (x.GrandSlamWin < y.GrandSlamWin)
            {
                return 1;
            }
            // 降順にソートしたいので、x > y に-1を割り当て
            else if (x.GrandSlamWin > y.GrandSlamWin)
            {
                return -1;
            }
            else
            {
                return 0;
            }
        }
    }

目次にもどる

(1-5) STEP3:ソートの実行

ここまで来たら実際にソートしたいListを定義して、要素を追加してSort()メソッドを実行する事でソートが行えます。Sortメソッドの引数には先ほど定義したBig4Comparerクラスのインスタンスを与えます。

(STEP3)

            // var(暗黙型)でBig4Players2のリストを定義
            var big4 = new List();
            // リストに要素を追加
            big4.Add(new Big4Players2() { Name = "Roger Federer", GrandSlamWin = 20 });
            big4.Add(new Big4Players2() { Name = "Rafale Nadal", GrandSlamWin = 20 });
            big4.Add(new Big4Players2() { Name = "Novak Djokovic", GrandSlamWin = 17 });
            big4.Add(new Big4Players2() { Name = "Andy Murray", GrandSlamWin = 3 });
            // ソートの実行(内部的にCompareメソッドが使われる)
            big4.Sort(new Big4Comparer());

目次にもどる

(1-6) サンプルプログラム

上記STEP0~STEP3までを繋げて、main文などを追記して実行可能にしたものを掲載します。

プログラム中で登場するvar(暗黙型)については別記事でも説明しているため、興味ある方は併せてご覧いただけたらと思います。

参考①:C#のvarの使いどころは?初めての方に向けてサンプルプログラムを使ってご紹介
参考②:C#のvarとは?型を調べる方法や制約事項についてもご紹介

(サンプルプログラム)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IComparerTest
{
    // STEP1:IComparerインターフェイスの実装
    class Big4Comparer : IComparer<Big4Players2>
    {
        // STEP2:Compareメソッドの実装
        public int Compare(Big4Players2 x, Big4Players2 y)
        {
            // 降順にソートしたいので、x < y に1を割り当て
            if (x.GrandSlamWin < y.GrandSlamWin)
            {
                return 1;
            }
            // 降順にソートしたいので、x > y に-1を割り当て
            else if (x.GrandSlamWin > y.GrandSlamWin)
            {
                return -1;
            }
            else
            {
                return 0;
            }
        }
    }

    class Big4Players2
    {
        // メンバ変数
        public string Name { get; set; }
        public int GrandSlamWin { get; set; }
        // コンソール出力用のメソッド
        public override string ToString()
        {
            return $"{this.Name} {this.GrandSlamWin}";
        }
    }

    class Program2
    {
        static void Main(string[] args)
        {
            // var(暗黙型)でBig4Players2のリストを定義
            var big4 = new List<Big4Players2>();
            // リストに要素を追加
            big4.Add(new Big4Players2() { Name = "Roger Federer", GrandSlamWin = 20 });
            big4.Add(new Big4Players2() { Name = "Rafale Nadal", GrandSlamWin = 20 });
            big4.Add(new Big4Players2() { Name = "Novak Djokovic", GrandSlamWin = 17 });
            big4.Add(new Big4Players2() { Name = "Andy Murray", GrandSlamWin = 3 });
            // ソートの実行(内部的にCompareメソッドが使われる)
            big4.Sort(new Big4Comparer());
            big4.ForEach(big4player => Console.WriteLine(big4player));
        }
    }
}

(図161)実行結果

目次にもどる

 

Adsense審査用広告コード


Adsense審査用広告コード


-C#

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

C#のデリゲートが分からない・・を解決!初心者向けになるべく分かり易く説明してみた

<目次> (1) C#のデリゲートが分からない・・を解決!初心者向けになるべく分かり易く説明してみた  (1-1) デリゲートとは?「関数へのポインタ」だけでは説明しきれない・・  (1-2) デリゲ …

C#でNLogライブラリを用いてログ出力を行う方法

<目次> (1) C#でNLogライブラリを用いてログ出力を行う方法  (1-1) NLogの概要  (1-2) NLogの導入手順  (1-3) NLogの初期実装手順  (1-4) NLogのサン …

C#のIEnumerableとは?使い方(foreachでの要素取り出し)を順を追って解説

<目次> (1) C#のIEnumerableとは?使い方(foreachでの要素取り出し)を順を追って解説  (1-1) IEnumerableとは?  (1-2) IEnumerableの実装の流 …

Xamarin.Formsのプロジェクトの構成について~各ファイルの役割や概要について~

<目次> (1) Xamarin.Formsのプロジェクトの構成について  (1-1) プロジェクト構造の概要  (1-2) プロジェクトの初期ファイルの一覧 (1) Xamarin.Formsのプロ …

C#のDB接続時のエラー(provider: Named Pipes Provider, error: 40 – Could not open a connection to SQL Server)

<目次> (1) 記事の目的  (1-1) エラー概要  (1-2) エラー原因  (1-3) エラー対策   (1-3-1) SQLServer:リモート接続を有効化   (1-3-2) SQLSe …

  • English (United States)
  • 日本語
Top