Атрибуты в переопределении метода

1

У меня есть базовый класс с методом. Производные классы просто должны украсить этот метод атрибутом (по-разному для каждого производного класса) и оставить тело нетронутым.

Я сделал что-то вроде

Базовый класс

public virtual int Method1()
{
    // body
}

public virtual int Method2()
{
    // body
}

Производный класс A

[AttributeA(ParameterName = "AName", CommandName = "ACommand")]
public override int Method1()
{
    return base.Method1();
}

[AttributeA(ParameterName = "AnotherName", CommandName = "AnotherCommand")]
public override int Method2()
{
    return base.Method2();
}

Производный класс B

[AttributeB(ParameterName = "BName", CommandName = "BCommand")]
public override int Method1()
{
    return base.Method1();
}

[AttributeB(ParameterName = "BnotherName", CommandName = "BnotherCommand")]
public override int Method2()
{
    return base.Method2();
}

и он работает, но мне это не кажется очень красивым, главная причина в том, что он оставляет клиенту свободу переопределять тело метода, чего я бы скорее избежал, а также утомительно просто повторить return base.Method(); ,

Существует ли более чистый подход к решению такого рода проблем? Мне что-то не хватает?

  • 0
    Можете ли вы просто применить атрибут к классу? Было бы полезно, если бы вы предоставили больше контекста о том, для чего этот атрибут.
  • 0
    @JonSkeet, как я написал, атрибут будет отличаться для каждого производного класса. Базовый класс - это контроллер mvc, и я использую атрибуты для обеспечения каких-либо проверок авторизации. Это таможенные атрибуты, и есть один для каждого производного контролера. Я добавлю пример.
Показать ещё 2 комментария
Теги:
override

2 ответа

0
Лучший ответ

Нет другого способа сделать это.

Около...

"также утомительно просто повторить базу возврата.Method(); [...]"

... Я бы сказал, что Visual Studio автоматически генерирует этот код для вас, что означает, что он стоит усилий (переопределяя применение новых атрибутов).

На самом деле это основное дизайнерское решение на языках.NET, поскольку отражение на атрибутах предоставляет метод Type.GetCustomAttributes(...) и имеет перегрузку, которая принимает входной параметр, называемый inherit и видит его описание:

inherit Тип: System.Boolean

true для поиска в этой цепочке наследования членов, чтобы найти атрибуты; в противном случае - false. Этот параметр игнорируется для свойств и событий [...]

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

Может быть, вы ищете что-то вроде этого (я придумал новый синтаксис С#!):

[AttributeA]
public metadataoverride int MethodA();
0

Затем вы должны вызвать метод косвенным.
Создайте метод обертки, который выполняет весь базовый код, который не следует переопределять:

private int MethodInternal() {

    // do common stuff here
    // original body of Method()

    return Method();
}

Тело Method() в базовом классе пуст, оно просто для возможности ввода кода.

Это делает обращение к return base.Method() в высших классах ненужным.

Пример:

Базовый класс

public virtual int Method()
{
    // empty
}

Производный класс A

[AttributeA]
public override int Method()
{
    // no return base.Method() required
    return ???
}
  • 0
    Я не понимаю ответ, предоставленный. Хотите добавить код? Спасибо
  • 0
    Теперь я вижу, что клиент все равно сможет переопределить тело Method () и добавить код, чего я бы предпочел избежать, как я уже писал.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню