Есть ли какой-нибудь элегантный способ выполнить определенный код в зависимости от вызывающего, используя отражение или иным образом?

В моем идеальном мире то, что я ищу, могло бы существовать примерно так:

public string UserDefinedField
{
    get { return _userDefinedField; }
    internal set { _userDefinedField = value; }        
    set { _userDefinedField = value; ChangedFields.Add(Fields.UserDefinedField); }
}

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
252
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий
public string UserDefinedField
{
    get { return _userDefinedField; }
    set { SetField(value); ChangedFields.Add(Fields.UserDefinedField); }
}

// Call this from internal methods and use the public property for other cases
internal string SetField(string userValue)
{
    _userDefinedField = userValue;
}

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

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

...
internal void SetUserDefinedField(string val) {
  _userDefinedField = val;
}
...

Переосмысление ответа Исака

public string UserDefinedField
{
    get { return InternalUserDefinedField; }
    set { InternalUserDefinedField = value; ChangedFields.Add(Fields.UserDefinedField); }
}

internal string InternalUserDefinedField 
{
    get { return _userDefinedField; }
    set { _userDefinedField= value;  }
}

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

// assumes callers know where they're located at in the current stack trace.
private Boolean IsExternallyCalled(int methodDepth)
{
    System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace();

    System.Type callingType = trace.GetFrame(methodDepth).GetMethod().ReflectedType;
    System.Reflection.Assembly a = System.Reflection.Assembly.GetAssembly(callingType);

    return !(a.Equals(System.Reflection.Assembly.GetCallingAssembly()));
}

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

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