Jer*_*ers 6 c# parameters methods
记录时,总是会纠缠于字符串文字中.
我解决了很好的性能,通过传递一个字段和变量Expression<Func<T>> expression(如解释在这里),所以你可以做这样的事情:
public void Demo(string someArgument)
{
LogFrameWork.LogLine("Demo"); // goal is to get rid of these string literals
LogFramework.Log(() => someArgument);
}
Run Code Online (Sandbox Code Playgroud)
我想为方法Demo本身做类似的事情:
public void Demo(string someArgument)
{
LogFramework.Log(this.Demo);
}
Run Code Online (Sandbox Code Playgroud)
我尝试过这样的事情:
public static void Log(Delegate method)
{
string methodName = method.Method.Name;
LogLine(methodName);
}
Run Code Online (Sandbox Code Playgroud)
还有这个:
public static void Log(Action method)
{
string methodName = method.Method.Name;
LogLine(methodName);
}
Run Code Online (Sandbox Code Playgroud)
但我得到这样的编译器错误:
Argument 1: cannot convert from 'method group' to 'System.Delegate'
Argument 1: cannot convert from 'method group' to 'System.Action'
Run Code Online (Sandbox Code Playgroud)
我可以使用Func <...>和Action <...>引入一堆重载,但这听起来过于复杂.
对于任何具有任意数量参数和可选结果的方法,有没有办法覆盖这个?
--jeroen
PS:我认为这个问题在这里可能有一些相关性,但没有答案让我感到'aha'的感觉:-)
您也可以在不使用ExpressionTrees的情况下实现此目的System.Diagnostics.StackTrace.
StackTrace trace = new StackTrace();
Run Code Online (Sandbox Code Playgroud)
然后:
trace.GetFrame(0).GetMethod().Name
Run Code Online (Sandbox Code Playgroud)
要获取MethodInfo,然后获取当前方法的名称,或者:
trace.GetFrame(1).GetMethod().Name
Run Code Online (Sandbox Code Playgroud)
获得调用方法.
这比它看起来要困难得多.我认为你可能最好使用泛型Func和Action重载,但是有一种方法可以用表达式树做到这一点.这是LINQPad中的一个例子:
public static void Log(Expression<Action> expr)
{
Console.WriteLine(((MethodCallExpression)expr.Body).Method.Name);
}
void Main()
{
Log(() => DoIt());
Log(() => DoIt2(null));
Log(() => DoIt3());
}
public void DoIt()
{
Console.WriteLine ("Do It!");
}
public void DoIt2(string s)
{
Console.WriteLine ("Do It 2!" + s);
}
public int DoIt3()
{
Console.WriteLine ("Do It 3!");
return 3;
}
Run Code Online (Sandbox Code Playgroud)
这输出:
DoIt DoIt2 DoIt3
请注意,我必须使用lambdas并在调用Log方法时指定伪参数.
这是基于Fyodor Soikin的优秀答案.
不要尝试将方法作为参数传递给记录器,而是从让记录器识别调用方法的角度来看待它。
这是一个(伪)示例:
记录器类
public void Debug( string message )
{
message = string.Format( "{0}: {1}", GetCallingMethodInfo(), message );
// logging stuff
}
/// <summary>
/// Gets the application name and method that called the logger.
/// </summary>
/// <returns></returns>
private static string GetCallingMethodInfo()
{
// we should be looking at the stack 2 frames in the past:
// 1. for the calling method in this class
// 2. for the calling method that called the method in this class
MethodBase method = new StackFrame( 2 ).GetMethod();
string name = method.Name;
string type = method.DeclaringType.Name;
return string.Format( "{0}.{1}", type, name );
}
Run Code Online (Sandbox Code Playgroud)
任何使用记录器的地方:
// resides in class Foo
public void SomeMethod()
{
logger.Debug("Start");
}
Run Code Online (Sandbox Code Playgroud)
记录器的输出将是:Foo.SomeMethod: Start