Невидимые входные параметры

Есть метод с параметрами по умолчанию. Требуется разделить способы вызова метода, а именно - если вызывается в родной сборке, возможность изменения параметров остается, если во внешней сборке, вызывается без изменения параметров по умолчанию.

Перегрузками невозможно, поясню:

static void Foo([CallerMemberName] string methodname = null)
   {
      Console.WriteLine(methodname);
   }

Вызов метода:

Foo();      // вызов возможен в любой сборке 
Foo("Bar"); // вызов возможен только в родной сборке

Иными словами нужен запрет на инициализацию параметров по умолчанию во внешней сборке, в идеале они должны быть просто невидимы.

Что не получилось: разные оболочки для метода, в этом cлучае methodname - имя оболочки, а не реально вызывающего метода. Что ожидаемо не получится - оценка изменений параметров по умолчанию, они изменяются всегда - либо задаются в вызове, либо изменяются вследствие атрибута. И отследить, кто их изменил и выбросить исключение вряд ли возможно.

Добавить in или out тоже вряд ли - параметр, скорее всего, может быть и в том, и в другом статусе.

Есть варианты, идеи?

Спасибо.

UPD1. Уточню проблему. Полный набор параметров выглядит примерно так:

static void Foo(string str1=null, string str2=null,[CallerMemberName] string methodname = null)

причем неатрибутированных параметров штуки 3, а то и 4. Поскольку они тоже дефолтные, то в итоге спиок вызова может включать от нуля до максимума параметров, и в этих условиях компилятор просто не соображает - то ли это str2, то ли methodname. Пока что это разрешается на уровне XML Comment'ов атрибутированных параметров - типа: "Don't change!", но кто их читает...

UPD2. @Alexander Petrov преложил обернуть атрибутированные параметры в классы. На самом деле эту возможность я обдумывал ранее, однако предположил, что в этой ситуации CallerMemberName будет обращаться к обертке. Но решил попробовать и, в принципе, получилось. Вызов сейчас выглядит примерно так:

Foo (new MemberName()); // или
Foo ("Bar", new MemberName())

Более того, для тех, кто не совсем в теме - таких аналогичных дефолтных атрибутов 4: CallerFilePath, CallerMemberName, int CallerLineNumber, и похожий на эти три string ParamName (префикс немного отличается). Обертка позволяет все 4 атрибутированных параметров упрятать в один Context(). Таким образом, ошибка связанная с путаницей параметров исключается - сложно представить, что кто-то захочет в качестве Str2 передать класс Context.

Однако возникла другая проблема. Параметр Context context - обязательный, т.е. всегда указывается в вызове. А поскольку его основная цель отработать по умолчанию, его указание в вызове излишне и желательно его избежать, пока же вот так:

// определение
static void Foo(MemberName membername, string str1=null, string str2=null) 
=> Console.Writeline ($"{membername} {str1} {str2}");

// обертка
    public class MemberName
{
    public string ToString = null;
    public MemberName([CallerMemberName] string memberName = null) => ToString = memberName;
}

// вызов
Foo (new MemberName());
// или
Foo ("Bar", new MemberName());

Спасибо всем, особенно @Alexander Petrov. Окончательный вариант будет оформлен в виде ответа.


Ответы (0 шт):