メソッドの引数の名前を式ツリーから取得する

メソッドに渡された引数の値が null でないことや空文字でないことなどを検証するために、
次のようなコードを記述することと思います。


static void Method1(string parameter1)
{
    if (parameter1 == null) throw new ArgumentNullException("parameter1");
    if (parameter1.Length == 0) throw new ArgumentException("値を空にすることはできません。", "parameter1");

    // 以下省略。
}


このようなコードは頻繁に必要になるので、コード スニペットを用意しておくと便利です

メソッド チェーンにしたい場合は、次のように拡張メソッドを使います。


static class Program
{
    static string[] Separate(this string text)
    {
        return text
            .AssertArgumentNotNull("text")
            .AssertArgumentNotEmpty("text")
            .Split(‘:’)
            .Select(s => s.Trim())
            .ToArray();
    }
}

[DebuggerNonUserCode]
public static class Assert
{
    public static T AssertArgumentNotNull<T>(this T value, string name) where T : class
    {
        if (value == null) throw new ArgumentNullException(name); 
        return value;
    }

    public static string AssertArgumentNotEmpty(this string value, string name)
    {
        if (value.Length == 0) throw new ArgumentException("値を空にすることはできません。", name); 
        return value;
    }
}


上記の方法ではメソッドの引数の名前を文字列のリテラル ("parameter1" のような形式) で記述することになりますが、
どうしてもこれを避けたい場合、ラムダ式による式ツリー (式木, Expression Tree) を利用することによって実現できます。


static class Program
{
    static void Method1(string parameter1)
    {
        Assert.IsArgumentNotNull(() => parameter1);
        Assert.IsArgumentNotEmpty(() => parameter1);

        // 以下省略。
    }
}

[DebuggerNonUserCode]
public static class Assert
{
    public static void IsArgumentNotNull<T>(Expression<Func<T>> getValue) where T : class
    {
        var body = (MemberExpression)getValue.Body;
        var field = (FieldInfo)body.Member;
        var value = getValue.Compile()();

        if (value == null) throw new ArgumentNullException(field.Name);
    }

    public static void IsArgumentNotEmpty(Expression<Func<string>> getValue)
    {
        var body = (MemberExpression)getValue.Body;
        var field = (FieldInfo)body.Member;
        var value = getValue.Compile()();

        if (value.Length == 0) throw new ArgumentException("値を空にすることはできません。", field.Name);
    }
}


Expression<TDelegate>.Compile メソッドを呼び出すことで、式ツリーをデリゲートに変換しています。

バージョン情報
.NET Framework 3.5, 4

参照
式ツリー (C# および Visual Basic)

カテゴリー: .NET Framework. タグ: . Leave a Comment »

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。