День 2273. #ЗаметкиНаПолях
Подробный Обзор CallerMemberName. Начало
Имена методов меняются. И если вы используете имена методов в нескольких местах, указывая их вручную в виде строк, вы потратите много времени на их обновление. К счастью, в C# мы можем использовать атрибут CallerMemberName.
Его можно применить к параметру в сигнатуре метода, чтобы его значением во время выполнения было имя вызывающего метода:
public void SayMyName(
[CallerMemberName] string? methodName = null) =>
Console.WriteLine($"Моё имя {methodName ?? "NULL"}!");
Важно отметить, что параметр должен быть обнуляемой строкой. Если вызывающий объект устанавливает значение параметра, используется оно. В противном случае используется имя вызывающего метода (если оно есть).
1. Прямой вызов
public void DirectCall()
{
Console.WriteLine("Прямой вызов:");
SayMyName();
}
Вывод:
Прямой вызов:
Моё имя DirectCall!
Мы не указываем значение параметра methodName в SayMyName, поэтому по умолчанию используется имя вызывающего метода: DirectCall.
2. Явная передача параметра
public void DirectCallWithName()
{
Console.WriteLine("Прямой вызов с параметром:");
SayMyName("Уолтер Уайт");
}
Вывод:
Прямой вызов с параметром:
Моё имя Уолтер Уайт!
Важно отметить, что компилятор устанавливает значение methodName, только если оно не обозначено явно. При этом явная передача null
SayMyName(null);
приведёт к тому, что значение methodName будет null.
3. Вызов через Action
public void CallViaAction()
{
Console.WriteLine("Вызов через Action:");
Action<int> action = (_) => SayMyName();
var calls = new List<int> { 1 };
calls.ForEach(s => action(s));
}
Вывод:
Вызов через Action:
Моё имя CallViaAction!
Здесь интереснее: атрибут CallerMemberName распознаёт имя метода, содержащего общее выражение. Здесь синтаксически вызывающим является метод ForEach, но он игнорируется, поскольку фактический вызов происходит в методе CallViaAction. Во время компиляции, поскольку методу SayMyName не передаётся значение, оно автоматически заполняется именем родительского метода. Затем метод ForEach вызывает SayMyName, но methodName уже определён во время компиляции.
4. Лямбда-выражения
То же происходит и при использовании лямбда-выражений:
public void CallViaLambda()
{
Console.WriteLine("Вызов через лямбду:");
void lambdaCall() => SayMyName();
lambdaCall();
}
Вывод:
Вызов через лямбду:
Моё имя CallViaLambda!
Окончание следует…
Источник: https://www.code4it.dev/csharptips/callermembername-attribute/
>>Click here to continue<<