查找传递给函数的变量名

时间:2020-03-05 18:55:54  来源:igfitidea点击:

让我用下面的例子来解释我的问题:

public string ExampleFunction(string Variable) {
    return something;
}

string WhatIsMyName = "Hello World"';
string Hello = ExampleFunction(WhatIsMyName);

当我将变量" WhatIsMyName"传递给示例函数时,我希望能够获得原始变量名称的字符串。也许像这样:

Variable.OriginalName.ToString()

有什么办法吗?

解决方案

回答

**不。**我不这么认为。

我们使用的变量名称是为了方便和可读性。编译器不需要它,如果我没有记错的话,只需将其剔除即可。

如果有帮助,我们可以定义一个名为NamedParameter的新类,其属性为Name和Param。然后,我们将该对象作为参数传递。

回答

我们想要的东西不可能直接实现,但是我们可以在C3.0中使用Expressions:

public void ExampleFunction(Expression<Func<string, string>> f) {
    Console.WriteLine((f.Body as MemberExpression).Member.Name);
}

ExampleFunction(x => WhatIsMyName);

请注意,这依赖于未指定的行为,尽管它确实可以在Microsoft当前的Cand VB编译器和Monos Ccompiler中工作,但不能保证它不会在将来的版本中停止工作。

回答

简短的答案是"不...",除非我们真的有上进心。

唯一的方法是通过反射和堆栈遍历。我们将必须获得一个堆栈框架,在要从中调用的调用函数中计算行踪,然后使用CodeDOM尝试找到树的正确部分以查看表达式是什么。

例如,如果调用是ExampleFunction(" a" +" b"),该怎么办?

回答

否。对字符串变量的引用将传递给函数-没有包含任何固有的元数据。即使是反思也不会使我们脱颖而出-从单个引用类型向后工作并不能为我们提供足够的信息来完成我们需要做的事情。

最好回到这个图板上!

rp

回答

我们可以使用反射来获取对象的所有属性,然后遍历对象,并获取(属性的名称)与传入的参数匹配的属性的值。

回答

好了一下。当然,我们不能使用任何类型信息。
另外,本地变量的名称在运行时不可用
因为它们的名称未编译到程序集的元数据中。

回答

不,但是只要我们发现自己做这种非常复杂的事情,就可能需要重新考虑解决方案。请记住,代码应该比编写起来更容易阅读。

回答

System.Environment.StackTrace将为我们提供一个包含当前调用堆栈的字符串。我们可以解析该信息以获取信息,其中包括每个调用的变量名。

回答

感谢所有回复。我想我只需要继续做我现在正在做的事情即可。

对于那些想知道为什么我问上述问题的人。我有以下功能:

string sMessages(ArrayList aMessages, String sType) {
    string sReturn = String.Empty;
    if (aMessages.Count > 0) {
        sReturn += "<p class=\"" + sType + "\">";
        for (int i = 0; i < aMessages.Count; i++) {
            sReturn += aMessages[i] + "<br />";
        }
        sReturn += "</p>";
    }
    return sReturn;
}

我向它发送错误消息数组和一个CSS类,然后将其作为网页的字符串返回。

每次调用此函数时,都必须定义sType。就像是:

output += sMessages(aErrors, "errors");

如我们所见,我的变量称为aErrors,而css类称为error。我希望我的感冒可以根据我发送给它的变量名找出要使用的类。

再次感谢所有答复。

回答

GateKiller,我的解决方法有什么问题?我们可以简单地重写函数以使用它(我已经自由地实时改进了函数):

static string sMessages(Expression<Func<List<string>>> aMessages) {
    var messages = aMessages.Compile()();

    if (messages.Count == 0) {
        return "";
    }

    StringBuilder ret = new StringBuilder();
    string sType = ((MemberExpression)aMessages.Body).Member.Name;

    ret.AppendFormat("<p class=\"{0}\">", sType);
    foreach (string msg in messages) {
        ret.Append(msg);
        ret.Append("<br />");
    }
    ret.Append("</p>");
    return ret.ToString();
}

这样称呼它:

var errors = new List<string>() { "Hi", "foo" };
var ret = sMessages(() => errors);

回答

static void Main(string[] args)
{
  Console.WriteLine("Name is '{0}'", GetName(new {args}));
  Console.ReadLine();
}

static string GetName<T>(T item) where T : class
{
  var properties = typeof(T).GetProperties();
  Enforce.That(properties.Length == 1);
  return properties[0].Name;
}

更多详细信息在此博客文章中。