Я использую C # 7+, и мне известен атрибут [CallerMemberName]
, но я ищу атрибут, который бы дал мне имя аргумента.
Вариант использования: Проверка на null, даже с операторами ??
и ?
null, может быть немного утомительной с проверкой условий и выдачей правильных исключений с правильными значениями. Вот уже несколько месяцев я использую решение, вдохновленное какой-то статьей, которую я прочитал, и которую можно назвать «конструктором проверки аргументов». Будет использоваться что-то вроде этого:
public class MyClass
{
public void DoTheThing(IFoo foo, ICollection<IBar> bars, string specialText)
{
new ArgumentValidator()
.NotNull(foo, nameof(foo))
.NotNullOrEmpty(bars, nameof(bars))
.NotNullOrEmpty(specialText, nameof(specialText));
...rest of function
}
}
Если, например, foo
будет нулевым, то ArgumentValidator.NotNull(...)
выдаст новый ArgumentNullException
с именем параметра "foo". Этот подход делает проверку аргументов более лаконичной, и это единственная причина, по которой я это делаю.
Было бы очень хорошо, если бы мне не приходилось указывать nameof(...)
каждыйвремя. То есть я хотел бы иметь возможность сделать это:
new ArgumentValidator()
.NotNull(foo)
.NotNullOrEmpty(bars)
.NotNullOrEmpty(specialText);
Для того, чтобы сделать это, мне нужно было бы выяснить, как сделать NotNull(...)
и другие функциивыяснить имя аргумента.
Я пытался создать атрибут на основе параметров, я пытался посмотреть на Environment.StackTrace
(не в восторге ни от попыток разобрать это, ни от влияния на производительность), яЯ посмотрел на StackFrame
, я посмотрел на получение информации о типе класса -> информация о методе -> информация о параметре и пользовательских атрибутах, и я до сих пор не нашел пути вперед.
Iхотелось бы сделать атрибут, похожий на [CallerMemberName]
, но этот атрибут извлекал бы имя аргумента, который использовался для вызова функции, назначал его для оформленного параметра и выполнял быстро (другими словами, я хочуavoiЕсли возможно, буду составлять трассировку, особенно если я часто использую эти проверки).
Вот где я нахожусь:
[AttributeUsage( AttributeTargets.Parameter )]
class ArgumentNameAttribute : Attribute
{
public string SomeProperty { get; set; }
}
class Program
{
static void NotNull<T>( T argument, [ArgumentNameAttribute] string argumentName )
{
//how to get at the argumentName?
}
static void DoTheThing( string thing )
{
NotNull( thing );
Console.WriteLine( "hello world" );
}
static void Main( string[] args )
{
DoTheThing( "12345" );
}
}
С другой стороны, я будупринять другое решение, которое делает проверку аргументов краткой и выразительной.
Идеи?