获取传递给C#方法的参数的名称

时间:2011-05-17 03:15:19

标签: c#

void MyMethod(string something, params object[] parameters)
    {
      foreach (object parameter in parameters)
      {
        // Get the name of each passed parameter
      }
    }

例如,如果我按以下方式调用方法,我想获取名称“myFirstParam”和“anotherParam”。

string myFirstParam = "some kind of text";
string anotherParam = 42;
MyMethod("test", myFirstParam, anotherParam);

也许反思就是答案?也许这是不可能的?我知道this question的存在,但是这个解决方案在这里不起作用。

(请不要回答“这不是一个好主意”。这不是我的问题。)

6 个答案:

答案 0 :(得分:28)

这完全不可能。

以下是一些甚至没有意义的案例:

MyMethod("abc", new object[5]);
MyMethod("abc", "def");
MyMethod("abc", var1 + var2);
MyMethod("abc", SomeMethod());
MyMethod("abc", b ? a : c);
MyMethod("abc", new object()); 
MyMethod("abc", null);

实际上,局部变量名甚至没有编译到程序集中。

答案 1 :(得分:2)

除了SLaks的答案之外 - 变量名在运行时根本不可用。变量由堆栈槽表示,并由索引寻址。因此,即使您提供的示例也无法获取此信息,更不用说SLaks提供的所有这些示例。反思在这里没有帮助。什么都没有。

答案 2 :(得分:1)

这是不可能的,我想知道你为什么需要它。

答案 3 :(得分:0)

这个怎么样;

void MyMethod(string something, object parameters)
{
RouteValueDictionary dic = HtmlHelper.AnonymousObjectToHtmlAttributes(options);
}

MyMethod("test", new { @myFirstParam=""some kind of text", anotherParam=42);

这已在System.Web.MVC.Html InputExtension中实现。

我的灵感在我的代码中使用了这种技术。 它非常灵活。

不要打扰" Html"在辅助方法中命名。与帮助器方法中的html或html属性无关。

它只是将命名的匿名参数转换为RouteValueDictionary,这是一个具有IDictionary<string,object>接口的特殊字典,其中key包含参数名称,object是参数的值。

答案 4 :(得分:0)

使用反射和@Martin的空参数测试示例:

using System.Reflection;

public SomeMethod(ClassA a, ClassB b, ClassC c)
{
    CheckNullParams(MethodBase.GetCurrentMethod(), a, b, c);
    // do something here
}

访问参数名称:

public void CheckNullParams(MethodBase method, params object[] args)
{
    for (var i=0; i < args.Count(); i++)
    {
        if (args[i] == null)
        {
            throw new ArgumentNullException(method.GetParameters()[i].Name);
        }
    }
}

这适用于构造函数和公共方法,但我没有测试VS中的单元测试,因此可能存在一些运行时JIT问题(阅读上面引用的文章)。

编辑:刚刚注意到,这与linked answer基本相同。

答案 5 :(得分:-1)

我从死亡中提出这个问题!

查看C#6.0的新名称()运算符。它可以让你完全按照自己的意愿行事,而且实际上并不是一个坏主意。

一个好的用例是Argument Exceptions或INotifyPropertyChanged。 (特别是当你在混合中获得继承时)

示例:

interface IFooBar
{
    void Foo(object bar);
}

public class FooBar : IFooBar
{


    public void Foo(object bar)
    {
        if(bar == null)
        {
            //Old and Busted
            //throw new ArgumentException("bar");

            //The new HOTNESS
            throw new ArgumentException(nameof(bar)); // nameof(bar) returns "bar"

        }

        //....
    }

}

现在,如果您重命名参数&#39; bar&#39;关于方法&#39; Foo&#39;在IFooBar接口中,您的参数异常会相应更新(防止您忘记更改&#34; bar&#34;字符串)

实际上非常整洁!