有没有办法获取传递给方法的参数数组?
假设我有一个方法:
public void SomeMethod(String p1, String p2, int p3)
{
#if DEBUG
object[] args = GetArguments();
LogParamaters(args);
#endif
// Do Normal stuff in the method
}
有没有办法检索传递给该方法的参数数组,以便可以记录它们?
我有大量的方法,并且希望避免手动将参数按名称传递给记录器,因为人为错误将不可避免地蔓延。
我猜它将涉及某种形式的反射 - 这很好,因为它只会用于调试目的。
更新
更多信息:
我无法更改 SomeMethod 的方法签名,因为它作为 WebMethod 公开,并且必须复制它所模拟的遗留系统。
遗留系统已经记录了传入的参数。首先,新的实现将包装遗留系统,因此我希望记录传入 C# 版本的参数,以便我可以验证传入的参数是否正确以正确的顺序。
我只是想记录参数值和顺序,而不是它们的名称。
Say I have a method:
public void SomeMethod(String p1, String p2, int p3)
{
#if DEBUG
object[] args = GetArguments();
LogParamaters(args);
#endif
// Do Normal stuff in the method
}
Is there a way to retrieve an array of the arguments passed into the method, so that they can be logged?
I have a large number of methods and want to avoid manually passing the arguments by name to the logger, as human error will inevitably creep in.
I'm guessing it will involve reflection in some form - which is fine, as it will only be used for debugging purposes.
Update
A little more information:
I can't change the method signature of SomeMethod, as it is exposed as a WebMethod and has to replicate the legacy system it is impersonating.
The legacy system already logs the arguments that are passed in. To start with the new implementation will wrap the legacy system, so I'm looking to log the parameters coming into the C# version, so that I can verify the right parameters are passed in in the right order.
I'm just looking to log the argument values and order, not their names.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
如果您使用 Postsharp,您只需向要记录的方法添加一个属性即可。在此属性中,您可以编写日志记录代码,并且还将提供您需要的参数。这就是所谓的横切关注点和 AOP(面向切面编程)
If you use Postsharp you can simply add an attribute to the method you want to log. Within this attribute you can write the logging code and also will provide the arguments you need. This is known as cross cutting concerns and AOP (Aspect orientated programming)
我不确定访问调用堆栈的 API 是否提供了获取参数列表的方法。
然而,有一些方法可以注入 IL 来拦截方法调用并执行自定义代码。
我经常使用的库是 Gael Fraiteur 的 PostSharp,它包含一个运行 postbuild 并根据输出程序集注入 IL 的应用程序关于您正在使用的方面。您可以使用一些属性来修饰程序集、类型或单个方法。例如:
在此之后,您可以使用此属性来装饰您想要的方法:
I am unsure if the API to access the call stack provides a means to get the argument list.
However there are ways to inject IL to intercept method calls and execute custom code.
The Library I use frequently is PostSharp by Gael Fraiteur, it includes an application that runs postbuild and injects IL in your output assemblies depending on the Aspects that you are using. There are attributes with which you can decorate assemblies, types, or individual methods. For instance:
After this you can just decorate the method you want with this Attribute:
好吧,如果您只想传递值,您可以作弊并定义一个对象数组:
但这将导致对值类型进行装箱,并且不会为您提供任何参数名称。
假设我有一个方法:
更新:不幸的是反射不会自动为你完成这一切。您需要提供值,但可以使用反射来提供参数名称/类型:
如何获取方法参数的名称?
因此方法 sig 将更改为类似以下内容:
然后您可以强制/假设每个集合中的每个索引都相符,例如
methodNames[0]
的值为vals[0]
。Well, if you just want to pass the values, you can cheat and define an object array:
This will incur boxing on value types and also not give you any parameter names, however.
Say I have a method:
Update: unfortunately reflection will not do it all automatically for you. You will need to provide the values, but you can use reflection to provide the param names/types:
How can you get the names of method parameters?
So the method sig would change to something like:
Then you can enforce/assume that each index in each collection tallies, such that
methodNames[0]
has the valuevals[0]
.好吧 params 有助于日志调用,但不会帮助现有的方法签名。使用 AOP 框架 进行日志记录可能是一种更高效的方法?
Well params help with the log call, but won't help the existing method signatures. Logging using an AOP framework might be a more productive approach?
当然可以......查看这篇文章,它获取了参数的实际值。
如何枚举传递的方法参数
Sure can ...check out this post, it gets the actual values of the params.
how to enumerate passed method parameters
动态类型系统有一些功能可以做到这一点,但是您的类需要从动态基类继承
There's some functionality with the dynamic type system that can do it, but then your class needs to inherit from the dynamic base classes
在某些情况下可能不起作用,但应该可以帮助您入门:)
might not work in some scenarios but should get you started :)
只要您知道需要什么类型,就可以将它们记录到 SQL 数据库中。编写一个执行类型检查的方法,然后用参数(参数)值填充相应的数据库列。如果您有自定义类型,则可以使用类型名称并将其另存为字符串在其自己的特殊列中。
-编辑
此外,使用
MethodBase.Name
扩展方法,您可以将参数与将它们作为参数的方法关联起来,如下面另一篇文章所述。是一种跟踪使用的所有方法、参数和类型的便捷方法。这甚至是一个模糊的好主意吗? :)
As long as you know what types to expect you could log them in an SQL database. Write a method that does a type check, and then fills the appropriate DB column with the parameter (argument) value. If you have a custom type then you can use the type name and save that as string in it's own special column.
-Edit
Also, using the
MethodBase.Name
extension method, you could associate your parameters with the method that took them as arguments as mentioned in another post below. Be a handy way of keeping track of all methods used, and with which arguments, and of which type.Is this even vaguely a good idea? :)
以下是我想出的解决方案:
PostSharp 或其他 AOP 解决方案在这种情况下并不实用,所以不幸的是我不得不放弃这个想法。
看来,虽然可以使用反射来参数名称和类型,但访问运行时值的唯一方法是附加调试器。
请参阅此处了解更多信息:
StackOverflow< /a>
microsoft.public.dotnet.framework
因此,这仍然给我留下了大约 50 个需要手动添加日志记录的方法的问题。
反射救援...
此代码片段循环遍历类上的方法,并输出一个使用传递到方法中的参数初始化的 object[] 数组以及包含参数和方法名称的 Log 调用。
示例输出:
然后可以将该块粘贴到方法的顶部以实现所需的效果。
它比我想要的更加手动,但它比手动输入参数要好得多,而且更不容易出错。
Here's what I came up with as a solution:
PostSharp or another AOP solution wasn't really practical in this situation, so unfortunately I had to abandon that idea.
It appears that while it is possible to parameter names and types using reflection, the only way to access the runtime values is with a debugger attached.
See here for more info:
StackOverflow
microsoft.public.dotnet.framework
So that still left me with the problem of ~50 methods that needed this logging adding by hand.
Reflection to the rescue...
This code snippet loops through the methods on a class and outputs an object[] array initialised with the arguments passed into the method and a Log call containing the arguments and the method name.
Example output:
This block can then be pasted into the top of the method to achieve the required effect.
It is more manual than I would have liked, but it is a lot better than having to type the parameters by hand and far less error prone.