C#ジェネリッククラスとインターフェイス

C# コンピュータ
C#
オブジェクト指向プログラミングは、目的のプログラムの設計が頭の中でしっかり固まっていないと、なかなか取り掛かることが出来ません。自分の場合比較的小さなプログラムで済む要件が多いので複数のクラスを作成することは稀です。
また、オブジェクト指向プログラミングのメリットの一つである再利用が出来る点も個人的は余り利用する機会が無いです。そういえば昔似たようなコードを書いたことがあったなと思うことはありますが、過去に書いたソースコードを発掘するのが大変なので、将来流用しそうなコードを当ブログの記事として投稿してコードのデータベースにしています。

珍しくジェネリッククラスとインターフェイスを利用する機会がありましたので記事にしたいと思います。

ソースコード

ファイル名:IPager.cs

using System;
using System.Collections.Generic;
using System.Linq;

namespace EIV.ClassLib;

public interface IPager<T>
{
    public bool IsAny();
    public bool IsFirst();
    public bool IsLast();
    public int Count();
    public bool Next();
    public bool Previous();
    public bool First();
    public bool Last();
    public T? Current();
}

ファイル名:Pager.cs

using System;
using System.Collections.Generic;
using System.Linq;

namespace EIV.ClassLib;

public class Pager : IPager
{
    List _list = new();
    int _index = -1;

    public Pager(IEnumerable entries)
    {
        foreach(var entory in entries)
        {
            _list.Add(entory);
        }
        if (_list.Any()) _index = 0;
    }
    public bool IsAny() => _list.Any();
    public bool IsFirst() => IsAny() && (_index == 0);
    public bool IsLast() => IsAny() && (_index == _list.Count-1);
    public int Count() => _list.Count;
    public bool Next()
    {
        if (!IsAny() || IsLast()) return false;
        _index = _index + 1;
        return true;
    }
    public bool Previous()
    {
        if (!IsAny() || IsFirst()) return false;
        _index = _index - 1;
        return true;
    }
    public bool First()
    {
        if (!IsAny()) return false;
        _index = 0;
        return true;
    }
    public bool Last()
    {
        if (!IsAny()) return false;
        _index = _list.Count - 1;
        return true;
    }
    public T? Current() => IsAny() ? _list[_index] : default(T);
}// class;

説明

GUIアプリケーションのイメージビューア作成ていて、画像ファイルを連続表示する機能を実現するため、表示する画像の順番を管理するクラスになります。
クラス内に配列(List<T>)とインデックスを持ちNext()Previous()でインデックスを前後に移動させます。
アプリケーション的には次のページの画像や前のページの画像のファイル名を取り出すために使います。
実際利用する場合はPagerクラスを継承した派生クラスを利用することに成ります。具体的にはディレクトリ上の画像ファイルを扱うクラスとzipファイル内の画像を扱うクラスの2つを作成しました。この両者は画像ファイルの一覧の取得方法と、画像ファイルの読み込む方法が異なるだけであとは同じような動作をします。この同じ部分をPagerクラスに切り出してベースクラスとしています。今回の目的はファイル名の管理ですので配列の要素はstringになります。だだこのクラスは他の型でも使えそうなのでIPagerでインターフェイスも作成してみました。この場合要素をTとすることで任意の型を指定することが出来ます。
これの何が嬉しいかといいますと、アプリケーションでzipファイルの画像ファイルとローカルの画像ファイルを両方とも対応させる場合、コード内でifで分岐させる必要があり1つのメソッド内のコード量が多くなりがちになります。その点クラスにしファイルを分けることで、プログラムの見通し少し良くなります。
あと、クラスの継承の良い点としてベースクラスの変数に派生クラスのオブジェクトを代入できる点です。実際の機能はクラスが違うので異なりますが、利用する側は同じオブジェクトとしてメソッドなどを呼び出すことが出来ます。

個人でプログラミングをする場合どのようなコードを書くかは好きにしていいとは思いますが、同じコードを繰り返すことが多いなと感じた場合、オブジェクト指向ではどのようにするか調べてみると解決できるかもしれません。

コメント