Есть ли способ получить имя аргумента функции (не параметр)? - PullRequest
1 голос
/ 10 октября 2019

Я использую 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" );
    }
}

С другой стороны, я будупринять другое решение, которое делает проверку аргументов краткой и выразительной.

Идеи?

1 Ответ

0 голосов
/ 16 октября 2019

Никто еще не создал ответ, но в комментариях были упомянуты альтернативы:

  • Аспектно-ориентированное программирование (AOP)
  • Использование синтаксиса обнуляемого ссылочного типа в C # 8

Хотя они и не отвечали на конкретный вопрос, они отвечали общей цели более чистого способа обработки нулевых типов. Учитывая мой вопрос ответил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...