记录日志时,您总是会与字符串文字纠缠在一起。
我通过传递 Expression> 很好地解决了属性、字段和变量的问题。表达式
(如解释这里),所以你可以做这样的事情:
public void Demo(string someArgument)
{
LogFrameWork.LogLine("Demo"); // goal is to get rid of these string literals
LogFramework.Log(() => someArgument);
}
我想对方法 Demo
本身做类似的事情:
public void Demo(string someArgument)
{
LogFramework.Log(this.Demo);
}
我尝试了这样的事情:
public static void Log(Delegate method)
{
string methodName = method.Method.Name;
LogLine(methodName);
}
和这样的:
public static void Log(Action method)
{
string methodName = method.Method.Name;
LogLine(methodName);
}
但是我得到了这样的编译器错误:
Argument 1: cannot convert from 'method group' to 'System.Delegate'
Argument 1: cannot convert from 'method group' to 'System.Action'
我可以使用 Func<...> 和 Action<...>,但这听起来过于复杂。
对于具有任意数量的参数和可选结果的任何方法,有没有办法解决这个问题?
--jeroen
PS:我认为这个问题可能在这里有一些相关性,但没有答案这让我有一种“啊哈”的感觉:-)
When logging, you always get entangled in string literals.
I solved that nicely for properties, fields and variables by passing an Expression<Func<T>> expression
(as explained here), so you can do things like this:
public void Demo(string someArgument)
{
LogFrameWork.LogLine("Demo"); // goal is to get rid of these string literals
LogFramework.Log(() => someArgument);
}
I want to do something similar for the method Demo
itself:
public void Demo(string someArgument)
{
LogFramework.Log(this.Demo);
}
I tried things like this:
public static void Log(Delegate method)
{
string methodName = method.Method.Name;
LogLine(methodName);
}
and this:
public static void Log(Action method)
{
string methodName = method.Method.Name;
LogLine(methodName);
}
But I get compiler errors like these:
Argument 1: cannot convert from 'method group' to 'System.Delegate'
Argument 1: cannot convert from 'method group' to 'System.Action'
I could introduce a bunch of overloads using Func<...> and Action<...>, but that sounds overly complex.
Is there a way to cover this for any method with any number of parameters and an optional result?
--jeroen
PS: I think this question might have some relevance here, but no answers that got me a 'aha' feeling :-)
发布评论
评论(5)
您也可以通过 System.Diagnostics.StackTrace 实现此目的,无需使用 ExpressionTree。
然后:
获取 MethodInfo 以及当前方法的名称,或者:
获取调用方法。
You can also achieve this without using ExpressionTrees through
System.Diagnostics.StackTrace
.And then:
To get the MethodInfo and then name of the current method, or:
To get the calling method.
这比看起来要难得多。我认为您可能最适合使用通用 Func 和 Action 重载,但是有一种方法可以使用表达式树来做到这一点。下面是 LINQPad 中的一个示例:
此输出:
请注意,在调用 Log 方法时,我必须使用 lambda 并指定虚拟参数。
这是基于 Fyodor Soikin 的出色答案。
This is much harder than it looks. I think you might be best with the generic Func and Action overloads, but there is a way to do this with expression trees. Here's an example in LINQPad:
This outputs:
Note that I had to use lambdas and specify dummy arguments when calling the Log method.
This is based on Fyodor Soikin's excellent answer.
不要尝试将方法作为参数传递给记录器,而是从让记录器识别调用方法的角度来看待它。
这是一个(伪)示例:
Logger Class
在任何使用记录器的地方:
记录器的输出将是:
Foo.SomeMethod: Start
Instead of trying to pass the method in as a parameter to your logger, look at it from the perspective of having the logger identify the calling method.
Here's an (pseudo) example:
Logger Class
Anywhere that uses the logger:
The output from the logger will then be:
Foo.SomeMethod: Start
您可以定义一个委托,然后接受该委托作为参数。
您可以像这样调用 MyMethod:
或
查看此链接以获取更多信息:
http://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx
You can define a delegate, then accept that delegate as a parameter.
You can call MyMethod like this:
or
See this link for more information:
http://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx
试试这个:
然后你可以做...
我希望我正确理解了你的问题...这符合你的要求吗?
Try this:
Then you can do...
I hope I have understood your question correctly... does this do what you want?