0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C# 拡張メソッドの使い方

Last updated at Posted at 2021-06-27

#●拡張メソッド
既存クラスに、継承を使わずにメソッドだけ追加するための仕組み

#●拡張メソッド定義構文
拡張メソッドであることの条件は2つ
・staticクラスのstaticメソッドであること
・第1引数として、thisキーワードをつけて拡張するクラスを指定すること

public static 戻り値の型 拡張メソッド(this 拡張するクラス 引数名, その他の引数)
{
    メソッド本体
}

#●ソース

Sringクラスを拡張して、新たなRepeatメソッドを定義する。
指定回数だけ繰り返した文字列を取得

// Stringクラスを拡張したstaticクラス
// クラス名は、(対象のクラス+Extensions)とするといい
static class StringExtensions
{
    // thisキーワードでStringクラスを拡張することを指定
    // 第2引数意向で、拡張メソッド本来の引数を指定する(この場合はcount)
    public static string Repeat(this string str, int count)
    {
        var builder = new StringBuilder();
        for (int i = 0; i <= count; i++)
        {
            builder.Append(str);
        }
        return builder.ToString();
    }
}

DateTimeクラスを拡張して、EndOfMonthメソッドを定義する。
指定した日付の月の最終日を取得する

// DateTimeクラスを拡張したstaticクラス
static class DateTimeExtensions
{
    // thisキーワードでDateTimeクラスを拡張することを指定
    public static DateTime EndOfMonth(this DateTime date)
    {
        return new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
    }
}
static void Main(string[] args)
{
    var str = "Wow!";
    Console.WriteLine(str.Repeat(5));

    var date = DateTime.Now;
    Console.WriteLine(date.EndOfMonth());

}

#列挙型、インターフェースでの拡張メソッド
拡張メソッドは列挙型(Enum)やインターフェースにも使用することができる

##列挙型

// 調味料を列挙
enum Seasoning
{
    Salt,
    Soy_Sauce,
    Sugar
}

// Seasoningの拡張メソッド
static class SeasoningExtensions
{
    public static string GetSeasoningString(this Seasoning kind)
    {
        switch (kind)
        {
            case Seasoning.Salt:
                return "塩";
            case Seasoning.Soy_Sauce:
                return "醤油";
            case Seasoning.Sugar:
                return "砂糖";
            default:
                return "";
        }
    }
}
static void Main(string[] args)
{
    // 全ての列挙子(値)を取得して表示
    foreach (Seasoning kind in Enum.GetValues(typeof(Seasoning)))
    {
        Console.WriteLine(kind.GetSeasoningString());
    }
}

##インターフェース
実装を定義できないインターフェースでも拡張メソッドが利用可能。

static class Extensions
{
    // 条件で絞る機能の追加
    public static IEnumerable<int> Where(this IEnumerable<int> array, Func<int, bool> pred)
    {
        foreach (var x in array)
            if (pred(x))
                yield return x;
    }
    // 値を加工する機能を追加
    public static IEnumerable<int> Select(this IEnumerable<int> array, Func<int, int> filter)
    {
        foreach (var x in array)
            yield return filter(x);
    }
}

static void Main(string[] args)
{
    var input = new[] { 8, 9, 10, 11, 12, 13 };

    var output = input
        .Where(x => x > 10)
        .Select(x => x * x);
}

#まとめ
コードが読みやすくなったり、もう少し機能が欲しかったものに追加することができる反面、定義箇所が分かりづらくなるなどのデメリットもあるので、濫用は避けた方がいい。

#・参照
[拡張メソッド ++C++; // 未確認飛行 C ]
(https://ufcpp.net/study/csharp/sp3_extension.html#interface)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?