【C#】拡張メソッドを活用してコードを簡潔にしよう!【Unity】

拡張メソッドを活用してコードを簡潔に使用

拡張メソッドとは

拡張メソッドとは、既存の型やクラスに対して元の型の変更を行うことなくメソッドを追加することができる機能です。追加したメソッドも簡単に呼び出しが可能です。

using System.Linq;で定義して使う LINQ も拡張メソッドです。

拡張メソッドのルール

  • クラスを static にする
  • 追加する拡張メソッドも static にする
  • 拡張メソッドの第一引数は型自身を表す this 型 引数名 とする

拡張メソッドを作ってみる

実際に Unity で使える拡張メソッドを作ってみます。

例えば以下のように Transform の拡張メソッドクラスである TransformExtensions.cs を作成し、拡張メソッドの AddPosX()を追加します。

public static class TransformExtensions
{
    // 今のX位置から引数のX分だけ追加で移動
    public static void AddPosX(this Transform transform, float x)
    {
        var pos = transform.position;
        pos.x += x;
        transform.position = pos;
    }
}

拡張メソッドは以下のように呼び出します。
型は Transform なので、Transform 型の posの後にメソッドを表記することで呼び出しが可能です。

拡張メソッドを活用することでコードの重複が減り、簡潔に書けるようになります。

Transform pos = this.transform;
pos.AddPosX(10f);

拡張メソッド参考例

参考として、他にもいくつか拡張メソッドを紹介します。

IntExtensions.cs

public static class IntExtensions
{
    // 偶数かどうか判定
    public static bool IsEven(this int value)
    {
        return value % 2 == 0;
    }

    // 奇数かどうか判定
    public static bool IsOdd(this int value)
    {
        return value % 2 != 0;
    }

    // 数値が引数の min 以上 max 以下であるか
    public static bool InBetween(this int value, int min, int max)
    {
        return value.CompareTo(min) >= 0 && value.CompareTo(max) <= 0;
    }
}

使用例

int num1 = 2;
num1.IsEven(); // True

int num2 = 20;
num2.IsOdd(); // False

int num3 = 5;
num3.InBetween(2, 10); // True

StringExtensions.cs

using System;
using System.Collections.Generic;

public static class StringExtensions
{
    public static string Format(this string format, params object[] values)
    {
        return String.Format(format, values);
    }

    private static char[] STRING_COMMA_SEPARATOR = { ',' };
    public static IList<string> SplitComma(this string listString)
    {
        return listString.Split(STRING_COMMA_SEPARATOR, StringSplitOptions.RemoveEmptyEntries);
    }

    public static T ToEnum<T>(this string str)
    {
        Type enumType = typeof(T);
        return (T)Enum.Parse(enumType, str);
    }
}

CollectionExtensions.cs

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

public static class CollectionExtensions
{
    public static bool IsNullOrEmpty(this IList collection)
    {
        return collection == null || collection.Count == 0;
    }

    public static void AddRange<T, S>(this IList<T> list, params S[] values) where S : T
    {
        foreach (S value in values)
        {
            list.Add(value);
        }
    }

    public static bool AddIf<T>(this IList<T> list, Predicate<T> predicate, T item)
    {
        if (predicate(item))
        {
            list.Add(item);
            return true;
        }

        return false;
    }

    public static bool RemoveIf<T>(this IList<T> list, Predicate<T> predicate, T item)
    {
        if (predicate(item))
        {
            list.Remove(item);
            return true;
        }

        return false;
    }

    public static bool AddIfNotContains<T>(this IList<T> list, T item)
    {
        if (!list.Contains(item))
        {
            list.Add(item);
            return true;
        }

        return false;
    }
}

関連リンク

Linqメソッド簡易解説&使い方まとめ【C#】 LINQ のメソッド簡易解説 & 使い方まとめ【Unity】