Rainbow Engine

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

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

関連記事

ASP.NET MVCでURLのパラメータを取得する仕組み

  <目次> (1) ASP.NET MVCでURLのパラメータを取得する仕組み  (1-1) 前提知識:URLにパラメータを埋め込む方法  (1-2) URLのパラメータ取得方法  (1- …

ASP.NET MVCのRouteConfigを追加する方法を2つご紹介

  <目次> (1) ASP.NET MVCのRouteConfigを追加する方法を2つご紹介  (1-1) やりたい事の整理  (1-2) 方法1:通常のルーティング  (1-3) 方法2 …

ASP.NETのRazor入門~Razorとは?や使い方をご紹介

<目次> (1) ASP.NETのRazor入門~Razorとは?や使い方をご紹介  (1-1) Razorとは?  (1-2) 基本構文  (1-3) サンプルプログラム (1) ASP.NETのR …

C#のabstract(抽象クラス)とは?継承やoverrideの手順や使い方をご紹介

<目次> (1) C#の抽象クラスやabstractとは?意味や使い方をご紹介  (1-1) 抽象クラスとは?  (1-2) 抽象クラスの使い方   (1-2-1) 抽象クラスの定義   (1-2-2 …

ソフトウェアをインストールするバッチプログラムのご紹介

  <目次> (1) ソフトウェアをインストールするバッチプログラムのご紹介  (1-1) 概要  (1-2) 構文  (1-3) サンプルプログラム  (1-4) (応用)プロキシサーバが …

  • English (United States)
  • 日本語
Top