Убедитесь, что цель наследует некоторый интерфейс для пользовательского атрибута - PullRequest
2 голосов
/ 09 января 2012

Мне нужно создать некоторые пользовательские атрибуты, которые будут использоваться для моих функций отражения.

Вот пример использования, как я его вижу:

  • пользователь создает некоторый класс ипомечает его моим специальным атрибутом (например, [ImportantAttribute] )
  • , затем пользователь делает что-то с функциями из моей библиотеки.Эти функции находят классы с [ImportantAttribute] и что-то с ними делают

Основная проблема в том, что функции в моей библиотеке ожидают, что классы, отмеченные [ImportantAttribute] унаследовать мой интерфейс (например, IMyInterface )

Можно ли сообщить пользователю, если он пометит свой класс [ImportantAttribute] и забудетнаследовать IMyInterface во время компиляции, а не во время выполнения.Некоторый способ указать, что этот атрибут предназначен только для классов, которые наследуют IMyInterface .

То же самое с атрибутами для свойств и полей.

Ответы [ 2 ]

1 голос
/ 09 января 2012

Есть ли способ сообщить пользователю, если он пометит свой класс с помощью [ImportantAttribute] и забудет наследовать IMyInterface во время компиляции, а не во время выполнения

Простой ответ: нет , это невозможно.Не во время компиляции.Вы можете проверить это во время выполнения, используя рефлексию.

Лучшее, что вы можете сделать с атрибутами во время компиляции (за исключением некоторых специальных системных атрибутов, таких как Obsolete, которые непосредственно включены в компилятор), это указать ихиспользование с атрибутом [AttributeUsage].

0 голосов
/ 09 января 2012

Я использовал стратегию, которую вы упомянули в паре фреймворков, которые я с успехом построил. Одним из таких примеров является предоставление метаданных для инфраструктуры подключаемого модуля:

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
public class PluginAttribute : Attribute
{
    public string DisplayName { get; set; }
    public string Description { get; set; }
    public string Version { get; set; }
}

public interface IPlug
{
    void Run(IWork work);
}

[Plugin(DisplayName="Sample Plugin", Description="Some Sample Plugin")]
public class SamplePlug : IPlug
{
    public void Run(IWork work) { ... }
}

Это позволяет мне получать информацию о плагинах без необходимости их создания и чтения свойств метаданных.

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

...