Этот вопрос не о том, почему этот код не работает, а о том, есть ли какие-либо альтернативы для его работы . Я понимаю поведение сокрытия свойств и ключевое слово new
.
В базовом контроллере я определил метод с атрибутом фильтра, который принимает строковый параметр. Я хочу, чтобы значение, переданное атрибуту, было определено в производных классах. Атрибуты требуют постоянной времени компиляции, что вынуждает меня использовать свойство const
, запрещающее любую форму перегрузки / переопределения.
Вот код, который я закончил писать. К сожалению, ключевое слово new
скрывает только свойство в производном классе и не влияет на базовый класс.
Наблюдаемое поведение : при срабатывании действия DerivedController.DoSomething
активируется атрибут AttributeThatNeedsProperty
со значением параметра property
, равным valueToOverride
(из класса BaseController
)
Желаемое поведение : Когда срабатывает действие DerivedController.DoSomething
, атрибут AttributeThatNeedsProperty
активируется со значением параметра property
, равным overridenValue
(из класса DerivedController
)
// Note: This code certainly won't compile, it's a quick reproduction of my setup meant to hide the implementation detail noise from my actual code. Still, it should include all the elements needed to understand the question. If not, please ask for clarification
public abstract class BaseController : Controller
{
public const string PropertyToOverride = "valueToOverride";
[AttributeThatNeedsProperty(PropertyToOverride)]
public IActionResult DoSomething()
{
}
}
public class DerivedController : BaseController
{
public new const string PropertyToOverride = "overridenValue";
}
public class AttributeThatNeedsProperty : Attribute, IAuthorizationFilter
{
private string _property;
public AttributeThatNeedsProperty(string property)
{
_property = property;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
// [...]
}
}
Я подумал о двух решениях, ни одно из которых мне не нравится:
- Переопределить метод
DoSomething
в производном классе. Я не хочу идти по этому пути, потому что единственная цель BaseController
состоит в том, чтобы избегать переопределения чего-либо в производных классах.
- Делайте какие-то шаткие рефлексирующие вещи, чтобы изменить значение при компиляции, но я не хочу идти по этому пути, потому что рефлексия может легко стать довольно неясной и усложнить поддержку кода. Я немного исследовал этот вариант, и, похоже, нет никаких «нехитрых» способов сделать это, даже если это возможно.
Вопрос: Как передать константу времени компиляции из производного класса в атрибут, используемый в базовом классе, не используя ни отражения, ни переопределения метода в производном классе.