【问题标题】:Is it possible to get the original parameter name using nameof() in a lambda expression?是否可以在 lambda 表达式中使用 nameof() 获取原始参数名称?
【发布时间】:2016-06-25 22:09:47
【问题描述】:

我需要创建一个 CSV 样式的参数字符串映射到它们的值。 例如:

static void MyMethod(int i, string str, object obj, bool flag)
{
    string example = "i=123,str=Hello,obj=1.0,flag=false";
}

调用如下:

MyMethod(123, "Hello", 1.0, false);

我想要一个像字符串example 这样的输出。

我需要为具有许多不同签名的大量方法执行此操作,并且可能不会使用每个方法中的所有参数而没有明显的模式 - 所以我尝试创建一种方法来稍微自动化该过程。

我已尝试使用委托和 nameof 解决此问题:

delegate string GetParametersDelegate(params object[] parameters);

static GetParametersDelegate GetParametersFunc = (parameters) =>
{
    return string.Join(",", parameters
        .Select(parameter => nameof(parameter) + "=" + parameter));
};

调用如下:

static void MyMethod(int i, string str, object obj, bool flag)
{
    string notTheResultIWant = GetParameters(i, str, obj, flag);
    // notTheResultIWant = "parameter=123,parameter=Hello,parameter=1.0,parameter=false"
}

我发现这会导致使用 lambda 中的变量名称而不是原始参数名称 - 因此每个值都错误地从 lambda 映射到 parameter

我正在尝试做的事情甚至可能实现吗?还是有其他方法可以解决这个问题?

【问题讨论】:

  • 如何用所有这些参数创建一个类并传递它。这样您就可以“捕获”构造函数中的参数名称并在其他任何地方重用它们。
  • 我刚刚在问题中进行了澄清,但是有许多不同的方法签名-我可以看到您的建议,实际上这很有趣,我将看看它。我唯一担心的是这个类的指数级增长!
  • 这个问题对你有帮助吗? stackoverflow.com/questions/14489799/…
  • 确实如此 - 这是我解决此问题的另一种可能方式。但是,如果可能的话,我想避免反射,因为这段代码应该是高性能的。
  • 如果您想在运行时提高效率,最好使用 Roslyn 分析器/修复程序来验证并从方法签名中提取该信息。

标签: c# lambda c#-6.0 nameof


【解决方案1】:

我想出的一个解决方案是通过 MethodInfo 获取被调用方法的 ParameterInfo[]:

delegate string GetParametersDelegate(Delegate method, params object[] parameters);

static GetParametersDelegate GetParametersFunc = (method, parameters) =>
{
    var paramNames = method.Method.GetParameters().Select(pInfo => pInfo.Name);
    return
        paramNames.Select((name, index) => $"{name}={parameters[index]?.ToString() ?? "null"}")
            .Aggregate((a, b) => $"{a},{b}");
};

您可以致电:

static void MyMethod(int i, string str, object obj, bool flag)
{
    var method = (Action<int, string, object, bool>)MyMethod;
    var notTheResultIWant = GetParametersFunc(method, i, str, obj, flag);
}

【讨论】:

  • 如果您实际要使用参数,则不应使用_ 作为参数名称。
  • 谢谢。回答时应避免无意义的名称。编辑了我的答案。
猜你喜欢
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多