C# 如何获取调用方法的参数值? 问题:
我正在编写一些代码,需要能够从调用类的方法中获取参数的值。我知道如何获取ParameterInfo[]数组,但不知道如何获取值。这可能吗 如果是,我认为这与使用MethodInfo对象中的MethodBody属性有关,它允许您检查IL流,包括属性,但我不知道如何操作,而且我还没有在Google上找到适用的代码 代码C# 如何获取调用方法的参数值? 问题:,c#,reflection,dynamic,C#,Reflection,Dynamic,我正在编写一些代码,需要能够从调用类的方法中获取参数的值。我知道如何获取ParameterInfo[]数组,但不知道如何获取值。这可能吗 如果是,我认为这与使用MethodInfo对象中的MethodBody属性有关,它允许您检查IL流,包括属性,但我不知道如何操作,而且我还没有在Google上找到适用的代码 代码 //从调用该类的类中查找调用方法 公共类 { 公共静态void FindMethod() { 对于(int i=1;i
//从调用该类的类中查找调用方法
公共类
{
公共静态void FindMethod()
{
对于(int i=1;i
您不能使用StackFrame或StackTrace。但是,您可以使用一些拦截框架(例如Spring.NET中的AOP内容),以便掌握参数值。微软的Jonathan Keljo在中说:
不幸的是,从数据库中获取参数信息的唯一简单方法
今天的callstack带有调试器。如果你想做这件事
在应用程序中记录错误,并且您计划将错误日志发送回
你的支持部门,我们希望你能使用迷你转储
未来的目标。(如今,将小型转储与托管代码一起使用是一个很好的选择。)
问题不大,因为它没有包含足够的信息,甚至无法获取
默认情况下堆栈跟踪。带堆的小型转储更好,但不是“小型”
如果你知道我的意思。)
纯粹主义者会说,允许人们编写能够
调用堆栈上其他函数的参数会鼓励它们
打破封装,创建代码,这是非常脆弱的面对
改变(您的场景没有这个特殊问题,但我
听到其他人对这项功能的要求,不管怎样,大多数人
请求可以通过其他方式解决,比如使用线程存储。)但是,
更重要的是,这会对应用程序的安全性产生影响
如果允许使用插件,那么这些插件就有可能会在短时间内刮掉堆栈
敏感信息。我们当然可以将该功能标记为需要
完全信任,但这将使它在几乎所有情况下都无法使用
我听说过
乔纳森
所以。。。我猜简短的回答是“我不能”。这太糟糕了。如果你不自己反省堆栈,你就无法做到这一点(这是很脆弱的,因为许多优化可能意味着堆栈框架不是你所期望的,甚至传递的参数实际上也不是方法签名所建议的(优化JIT编译器完全有可能发现您只使用了对象/结构的子字段并传递它) ParameterInfo只是告诉您编译后的方法的签名,而不是传递的值 自动实现这一点的唯一现实方法是通过代码注入(通过类似AOP的方式)来创建数据,并在分析IL的基础上对其进行处理 这通常不是一个好主意,如果您需要调试某些东西,请使用调试器;如果您需要记录某些东西,请明确说明您所记录的内容 清楚地说,简单的反射技术无法以完全的通用性实现您的愿望请参见此处: 根据我答案中的所有注释,我认为这是不可能的。PropertyInfo类确实有一个GetValue方法,但这要求您拥有一个实际的对象,您希望从中获取值。是的,您可以这样做 您需要做的是使用IL反汇编程序(可在System.Reflection.Emit命名空间中实现)查找包含您要查找的参数值的操作数 从这个问题开始: 然后使用答案中提到的课程(来自Mono.Reflection)进行检查。类似如下:
var instructions = method.GetInstructions();
foreach (var instruction in instructions)
{
var methodInfo = instruction.Operand as MethodInfo;
if(methodInfo == null)
{
continue;
}
if (instruction.OpCode.Name.Equals("call") && methodInfo.Name.Equals("YourMethodHere"))
{
var value = (CastToMyType)instruction.Previous.Operand;
// Now you have the value...
}
}
不确定这算不算解决方案,但我在一个具体案例中工作过, 我想在每次修改一个浮点数时记录代码的变化 读取堆栈跟踪行上的文件以确定参数
public static Score operator +(Score x,float y) {
var st = new StackTrace(true);
var sf = st.GetFrame(1);
string paramName = File.ReadLines(sf.GetFileName()).ElementAtOrDefault(sf.GetFileLineNumber()-1).Split(new[] { "+=" }, StringSplitOptions.None)[1];
x.DebugString += (paramName+" "+y);
x.DebugString += System.Environment.NewLine;
x.val += y;
return x;
}
void Main(){
Score score = new Score();
float firstScore = 2;
float secondScore = -13;
score+=firstScore;
score+=secondScore;
Console.WriteLine(score.DebugString);
}
Output :
firstscore 2
secondScore -13
是的,您可以使用PostSharp PostSharp.Aspects.MethodInterceptionSpect解决方案进行解释:我没有从这最后一行代码中获取值。我获取了类似构造函数信息的内容?这段代码是否有小问题?您测试过吗?
public static Score operator +(Score x,float y) {
var st = new StackTrace(true);
var sf = st.GetFrame(1);
string paramName = File.ReadLines(sf.GetFileName()).ElementAtOrDefault(sf.GetFileLineNumber()-1).Split(new[] { "+=" }, StringSplitOptions.None)[1];
x.DebugString += (paramName+" "+y);
x.DebugString += System.Environment.NewLine;
x.val += y;
return x;
}
void Main(){
Score score = new Score();
float firstScore = 2;
float secondScore = -13;
score+=firstScore;
score+=secondScore;
Console.WriteLine(score.DebugString);
}
Output :
firstscore 2
secondScore -13