如何检查方法的参数是来自变量还是文字? [英] How to check if the parameter of a method comes from a variable or a literal?

查看:44
本文介绍了如何检查方法的参数是来自变量还是文字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个代码:

string variable = "hello";

myMethod(variable) //usage 1
myMethod("hello")  //usage 2

我能检测出上面这些方法用法之间的区别吗?

Can I detect the difference between the these method usage above?

推荐答案

需要 调试信息生成(除了没有,在调试和发布构建模式下),拥有源代码并部署它,并使用 查找传递给函数的变量名 修改后,我们可以像这样从堆栈帧中获取信息:

Requiring debug info generated (anything but none, in debug as well as in release build mode), having the source code and to deploy it, and using Finding the variable name passed to a function adapted we can get information from the stack frame like that:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

static class InstanceHelper
{

  static private Dictionary<string, (bool, string)> AlreadyAcessedVarNames
    = new Dictionary<string, (bool, string)>();

  static public (bool isLiteral, string value) NameOfFromStack(this object instance, int level = 1)
  {
    try
    {
      var frame = new StackTrace(true).GetFrame(level);
      string filePath = frame.GetFileName();
      int lineNumber = frame.GetFileLineNumber();
      string id = filePath + lineNumber;
      if ( AlreadyAcessedVarNames.ContainsKey(id) )
        return AlreadyAcessedVarNames[id];
      using ( var file = new StreamReader(filePath) )
      {
        for ( int i = 0; i < lineNumber - 1; i++ )
          file.ReadLine();
        string name = file.ReadLine().Split('(', ')')[1].TrimEnd(' ', ',');
        bool isLiteral = true;
        if ( name.Length > 0 )
          if ( ( char.IsLetter(name[0]) || name[0] == '_' || name[0] == '@' )
            && name != "null" & name != "false" && name != "true"
            && !name.StartsWith("@\"") )
            isLiteral = false;
        var result = (isLiteral, name);
        AlreadyAcessedVarNames.Add(id, result);
        return result;
      }
    }
    catch
    {
      return (true, "Internal Error in " + nameof(NameOfFromStack));
    }
  }

}

备注

  • level 为当前方法为 1,调用方为 2,依此类推.

  • The level is 1 for the current method, 2 for the caller, and so on.

这里的方法把整个参数列表视为一个,所以当有多个参数时,我们得到一个类似param1, param2, param3"的列表;我们将不得不在 name 上再次拆分,我们还应该向方法传递一个位置以获得所需的位置.

This method considers the whole parameter list to be one here, so when there are multiple parameters, we get a list like "param1, param2, param3" and we will have to split again on name and we should also pass a position to the method to get the desired.

测试

string myString = "hello";
int a = 10;
bool b = true;

MyMethod1(null);

MyMethod1(myString);
MyMethod1("hello");

MyMethod2(a);
MyMethod2(10);

MyMethod3(b);
MyMethod3(false);

static void MyMethod1(string msg)
{
  Console.WriteLine(msg.NameOfFromStack(2));
}

static void MyMethod2(int value)
{
  Console.WriteLine(value.NameOfFromStack(2));
}

static void MyMethod3(bool value)
{
  Console.WriteLine(value.NameOfFromStack(2));
}

输出

(True, null)
(False, myString)
(True, "hello")
(False, a)
(True, 10)
(False, b)
(True, false)

这篇关于如何检查方法的参数是来自变量还是文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆