Почему атрибуты информации о вызывающем абоненте реализованы так, как они есть?

Недостатки текущей реализации:

  • Они нарушают принцип СУХОГО, так как вы должны переписывать параметры везде, где они вам нужны
  • Они разрушают скрытие реализации, так как вы должны указать эти параметры уже в интерфейсе - даже если они нужны только одной реализации вашего интерфейса.
  • Они запачкают ваш интерфейс, пользователи видят их в автозаполнении, документации и т. П.

Почему дизайнеры языка решили не использовать что-то более полезное, например:

public void Foo()
{
    Console.WriteLine(CallerInformation.File);
}

Я предполагаю, что в этой реализации отсутствуют некоторые функции: например, если Foo() является классом, реализующим IFoo, а IFoo находится в другой сборке, как любой вызывающий IFoo во время компиляции должен знать, что информация требуется, - он не может этого знать.

Но! Не лучше ли задокументировать, что это работает только в пределах одного "шага сборки" вместо того, чтобы создавать что-то непригодное в качестве текущей реализации?

В1: Есть ли официальная документация о том, почему она реализована так, как сейчас?

Q2: кто-нибудь знает лучшее решение на других языках?

1 ответ

Атрибуты информации о вызывающем абоненте семантически связаны с аргументами метода (например, "Если для этого строкового параметра не указано значение, поместите в него имя члена вызывающего абонента вместо использования значения по умолчанию null"), поэтому я не вижу причин, почему они не должны быть связанным также синтаксически, как в настоящее время.

Они нарушают принцип СУХОГО, так как вы должны переписывать параметры везде, где они вам нужны

Другие подходы также должны были бы делать что-то каждый раз, когда он хочет присвоить имя вызывающего элемента переменной, например: param = param?? SomeExpressionToGetSomeValue

Они разрушают скрытие реализации, так как вы должны указать эти параметры уже в интерфейсе - даже если они нужны только одной реализации вашего интерфейса.

Относительно сокрытия реализации: обязанность вызывающей стороны предоставлять аргументы, поэтому это должно быть в интерфейсе (если среда выполнения не решит всегда предоставлять такую ​​информацию во всех вызовах, что было бы похоже на неявное предоставление аргументов - и предоставление аргументов неявно / магически за кулисами не кажется, лучший подход для меня)

Что касается необходимости указывать эти параметры уже в интерфейсе - даже если они нужны только одной реализации вашего интерфейса: указывайте только атрибут и параметр, если это необходимо. Вот почему Math.Abs ​​объявляется как public static int Abs(int value), а не как public static int Abs(int value, объект ThisIsNotNeededButLetsJustHaveItHereItAnyways)

Они запачкают ваш интерфейс, пользователи видят их в автозаполнении, документации и т. П.

Хм, я не понимаю, почему вы думаете, что это плохо - если звонящий должен указать свое имя, это должно быть в документации и т. Д.


Похоже, вы предлагаете себе что-то вроде чтения стековых фреймов, и это скомпилирует и запустит, но может не дать ожидаемого результата:

private void SomeMethod()
{
    return new StackFrame(1).GetMethod().Name;
}

Приведенный выше код получит имя вызывающего во время выполнения, но оно может не совпадать с именем вызывающего во время компиляции из-за встраивания или оптимизации хвостового вызова.

Следовательно, если метод хочет получить информацию о вызывающей стороне, как это происходит во время компиляции (не во время выполнения), такой подход не будет работать.

Другие вопросы по тегам