В моем идеальном мире то, что я ищу, могло бы существовать примерно так:
public string UserDefinedField
{
get { return _userDefinedField; }
internal set { _userDefinedField = value; }
set { _userDefinedField = value; ChangedFields.Add(Fields.UserDefinedField); }
}
Где один оператор выполняется независимо от модификатора доступа, а другой оператор выполняется, если он вызывается из внешней сборки или класса.
Я уверен, что мог бы что-то закодировать, используя отражение и проверяя текущий стек вызовов, чтобы увидеть, находится ли вызывающий в той же сборке, но я ищу более элегантный подход, чем этот.





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()));
}
Проблема, с которой я столкнулся с другими опубликованными до сих пор примерами, заключается в том, что другим классам, даже в той же сборке, требуется внутреннее знание того, как работает этот конкретный класс, чтобы вызвать «правильный» установщик. Это не пахнет так, как если бы я наложил такое же ограничение на внешние сборки, но я бы предпочел разделить свои проблемы немного подробнее.