Получить имена параметров, переданных методу С#
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);
Возможно, размышление - это ответ? Возможно, это просто невозможно? Я знаю о существовании этого вопроса, но это решение не будет работать здесь.
(Пожалуйста, не отвечайте "Это не очень хорошая идея". Это не мой вопрос.)
Ответы
Ответ 1
Это абсолютно невозможно.
Вот лишь несколько случаев, когда это даже не имеет смысла:
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);
Фактически, локальные имена переменных даже не компилируются в сборку.
Ответ 2
В дополнение к SLaks ответ - имена переменных вообще не доступны во время выполнения. Переменные представляются слотами стека и адресуются индексом. Таким образом, вы не можете получить эту информацию даже для приведенного вами примера, не говоря уже обо всех этих примерах. Отражение здесь не помогает. Ничего нет.
Ответ 3
Это невозможно, и мне интересно, зачем вам это нужно.
Ответ 4
Как насчет этого?
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>
, где ключ содержит имя аргумента, а объект - значение аргумента.
Ответ 5
Использование отражения и пример @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 во время выполнения (чтение статей, упомянутых выше).
EDIT: только что заметил, это по сути то же самое, что связанный ответ.
Ответ 6
Я ПОДНИМАЮ ЭТОТ ВОПРОС ОТ МЕРТВОГО!
Обратите внимание на новый оператор name # (#) С# 6.0. Это позволяет делать то, что вы хотите, и на самом деле это не всегда плохая идея.
Хорошим вариантом использования является исключение Argument, или 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"
}
//....
}
}
Теперь, если вы переименовали параметр "bar" в методе "Foo" в интерфейсе IFooBar, ваши аргументы будут соответствующим образом обновляться (запрещает вам забывать изменить строку "bar" )
Довольно аккуратно!