1

多くの場合、式、パラメーター、ステートメントなどの名前が必要です。次に例を示します。

public abstract void Log(string methodName, string parameterName, string message);

public void FooMethod(string value)
{
    if (value == null)
    {
        this.Log("FooMethod", "value", "The value must be whatever...");
        throw new ArgumentNullException("value");
    }

    if (value.Length < 5)
    {
        this.Log("FooMethod", "value.Length", "The value length must be whatever...");
        throw new ArgumentException("value");
    }
}

たとえば、次のように使用できるキーワードを使用して、これらの文字列リテラルを自動的に取得する方法はありますtypeof(string)か?それとも、リフレクションに基づくシンプルでパフォーマンスの高いアプローチはありますか?

このパラメーターをチェックしてログに記録する方法を探していません(これは実際には単なる例です)。コードの一部をとして取得するメソッドを探していますstring

以下はより正確であり、コンパイラーによってチェックされ、コードをリファクタリングするときにも考慮されます。

public void FooMethod(string value)
{
    if (value == null)
    {
        this.Log(literal(this.FooMethod), literal(value), "The parameter '" + literal(value) + "' must be whatever...");
        throw new ArgumentNullException(literal(value));            
    }

    if (value.Length < 5)
    {
        this.Log(literal(this.FooMethod), literal(value.Length), "The value length must be whatever...");
        throw new ArgumentException(literal(value));
    }
}
4

3 に答える 3

2

考えられるすべてのタイプに対して、このような静的メソッドを作成できます。以下はメソッド名です。

public static string GetString(Action obj)
{
    return obj.Method.Name;
}

public static string GetString(Delegate obj )
{
    return obj.Method.Name;
}
于 2011-08-23T09:31:24.050 に答える
1

StackTrace.GetFrameが必要なようです。このメソッドは、この情報を見つけることができる必要なStackFrameオブジェクトを取得します。

次のコードサンプルを確認してください

StackFrame fr = new StackFrame(1,true);
StackTrace st = new StackTrace(fr);
this.Log.WriteEntry(fr.GetMethod().Name,
                    fr.GetMethod().GetParameters()[0].Name,
                    "The value must be whatever...");

ちなみに、2番目のコード例では、呼び出しの前に例外がスローされるため、Logメソッドの呼び出しは実行されません。finallyブロック内のコードを除いて、例外がスローされた後、メソッド内のコードは実行されません。この記事を参照してください。

于 2011-08-23T09:14:19.607 に答える
0

それはあなたの目標が何であるかに依存します。ランタイム値を取得したい場合は、MartinDomsの回答が解決策になる可能性があります。たとえば、ArgumentNullExceptionを特定の引数名にリンクできるようにし、名前を変更した場合にリファクタリングを使用できるようにする場合は、次のようにします。

 public static void NotNull<T>(Expression<Func<IEnumerable<T>>> exp)
        {
            var expBody = exp.Body as MemberExpression;
                T value = exp.Compile().Invoke();
                if (value == null){
                    string memberName;
                    if (expBody != null){
                        memberName = expBody.Member.Name;
                    } else{
                        memberName = "member";
                    }
                    throw new ArgumentNullException(memberName, memberName + " cannot be null");
                }
        }

その後、次のように使用できます。

public void Method(string value){
  Ensure.NotNull(()=>value);
}

値がnullかどうかを確認し、値がnullの場合は適切なメッセージをArgumentNullExceptionにフォーマットします。ただし、.NET 4.0を使用している場合は、代わりにこのようなもののコントラクトを使用することをお勧めします。ここで特定のニーズを実際に解決するわけではありませんが、コントラクトを使用した引数チェックは、「昔ながらの方法」で行う場合と比較して、ドキュメントと静的分析に関して多くの利点があります。

于 2011-08-23T09:48:32.223 に答える