Казалось бы, это означает «нет». Что прискорбно.
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class,
AllowMultiple = true, Inherited = true)]
public class CustomDescriptionAttribute : Attribute
{
public string Description { get; private set; }
public CustomDescriptionAttribute(string description)
{
Description = description;
}
}
[CustomDescription("IProjectController")]
public interface IProjectController
{
void Create(string projectName);
}
internal class ProjectController : IProjectController
{
public void Create(string projectName)
{
}
}
[TestFixture]
public class CustomDescriptionAttributeTests
{
[Test]
public void ProjectController_ShouldHaveCustomDescriptionAttribute()
{
Type type = typeof(ProjectController);
object[] attributes = type.GetCustomAttributes(
typeof(CustomDescriptionAttribute),
true);
// NUnit.Framework.AssertionException: Expected: 1 But was: 0
Assert.AreEqual(1, attributes.Length);
}
}
Может ли класс наследовать атрибуты интерфейса? Или я здесь не на то дерево лаю?
c#
attributes
Роджер Липскомб
источник
источник
Вы можете определить полезный метод расширения ...
Вот метод расширения:
Обновить:
Вот более короткая версия, предложенная SimonD в комментарии:
источник
Apply
на встроенныйForEach
отMicrosoft.Practices.ObjectBuilder2
Статья Брэда Уилсона об этом: Атрибуты интерфейса! = Атрибуты класса
Подводя итог: классы не наследуются от интерфейсов, они их реализуют. Это означает, что атрибуты не являются частью реализации автоматически.
Если вам нужно наследовать атрибуты, используйте абстрактный базовый класс, а не интерфейс.
источник
Хотя класс C # не наследует атрибуты своих интерфейсов, существует полезная альтернатива при связывании моделей в ASP.NET MVC3.
Если вы объявляете модель представления интерфейсом, а не конкретным типом, тогда представление и связыватель модели будут применять атрибуты (например,
[Required]
или[DisplayName("Foo")]
из интерфейса при рендеринге и проверке модели:Тогда в представлении:
источник
Это больше для людей, желающих извлечь атрибуты из свойств, которые могут существовать в реализованном интерфейсе. Поскольку эти атрибуты не являются частью класса, это даст вам доступ к ним. обратите внимание, у меня есть простой контейнерный класс, который дает вам доступ к PropertyInfo - именно для этого он мне нужен. Взламывайте сколько нужно. У меня это сработало.
источник
РЕДАКТИРОВАТЬ: это касается наследования атрибутов от интерфейсов на членах (включая свойства). Выше есть простые ответы на определение типов. Я просто разместил это, потому что нашел это раздражающим ограничением и хотел поделиться решением :)
Интерфейсы являются множественным наследованием и ведут себя как наследование в системе типов. Для такого рода вещей нет веской причины. Отражение - это немного банально. Я добавил комментарии, чтобы объяснить чушь.
(Это .NET 3.5, потому что это именно то, что я использую сейчас в проекте.)
Тест Barebones NUnit
источник
Добавьте интерфейс со свойствами, которые имеют атрибуты / настраиваемые атрибуты, прикрепленные к тем же свойствам, что и класс. Мы можем извлечь интерфейс класса, используя функцию рефакторинга Visual Studio. Имейте частичный класс, реализующий этот интерфейс.
Теперь получите объект «Type» объекта класса и получите настраиваемые атрибуты из информации о свойстве, используя getProperties для объекта Type. Это не даст настраиваемые атрибуты для объекта класса, поскольку к свойствам класса не были прикреплены / унаследованы настраиваемые атрибуты свойств интерфейса.
Теперь вызовите GetInterface (NameOfImplemetedInterfaceByclass) для полученного выше объекта Type класса. Это предоставит интерфейс "Type" объект. мы должны знать ИМЯ реализованного интерфейса. Из объекта Type получить информацию о свойствах, и если к свойству интерфейса прикреплены какие-либо настраиваемые атрибуты, информация о свойстве предоставит список настраиваемых атрибутов. Реализующий класс должен обеспечить реализацию свойств интерфейса. Сопоставьте имя конкретного свойства объекта класса в списке информации о свойствах интерфейса, чтобы получить список настраиваемых атрибутов.
Это сработает.
источник
Хотя мой ответ запоздалый и относится к определенному случаю, я хотел бы добавить несколько идей. Как предлагается в других ответах, Reflection или другие методы сделают это.
В моем случае свойство (временная метка) требовалось во всех моделях для удовлетворения определенного требования (атрибут проверки параллелизма) в основном проекте Entity framework. Мы могли либо добавить [] над всеми свойствами класса (добавление в интерфейс IModel, какие модели реализованы, не сработало). Но я сэкономил время с помощью Fluent API, который может пригодиться в этих случаях. В свободном API я могу проверить имя конкретного свойства во всех моделях и установить IsConcurrencyToken () в 1 строке !!
Аналогичным образом, если вам нужно добавить какой-либо атрибут к одному и тому же имени свойства в сотнях классов / моделей, мы можем использовать свободные методы api для встроенного или настраиваемого преобразователя атрибутов. Хотя EF (как ядро, так и EF6) fluent api может использовать отражение за кулисами, мы можем сэкономить усилия :)
источник