Классное использование атрибутов или аннотаций (CLR или Java)? - PullRequest
9 голосов
/ 28 января 2009

Какие классные приложения для пользовательских атрибутов в коде CLR / C # вы написали или о которых слышали? Также интересно новое использование стандартных атрибутов тоже хорошо!

Редактировать: Поскольку аннотации Java кажутся такими же, как атрибуты CLR, использование аннотаций Java также допустимо.

Ответы [ 8 ]

12 голосов
/ 28 января 2009
  • postsharp , который использует атрибуты для ввода кода (AOP)?
  • [TypeDescriptionProvider], который можно использовать для предоставления настраиваемой модели свойств среды выполнения - либо совершенно разные свойства, либо, возможно, более быстрые

И некоторые основные, которые часто упускаются из виду:

  • [TypeForwardedTo] - используется для перемещения типов между сборками без перестройки
  • [PrincipalPermission] - используется для автоматического обеспечения безопасности членов
8 голосов
/ 28 января 2009

Хотя это не совсем C #, я обнаружил интересное использование аннотаций Java (= атрибуты C #) для маркировки ученических заданий. Каждый семестр я программирую робота-разметчика для студентов, и оказывается, что студенты-первокурсники почему-то не в состоянии точно следовать инструкциям, что, конечно же, приводит к отказу робота-разметчика. Итак, что я делаю, так это просматриваю их код, нахожу все методы, которые не соответствуют спецификации, и исправляю их. Затем я поместил аннотацию (= атрибут) на каждый из методов, которые были неправильными, и сказал роботу-метке пометить их. Я думаю, это самый простой и прямой способ сделать это.

3 голосов
/ 28 января 2009

Проверьте xUnit и посмотрите, как атрибуты используются для маркировки модульных тестов для ожидаемого поведения, а также для подачи данных в тесты. Атрибуты используются более осмысленно, чем MSTest или NUnit.

Из Samples \ TestMethodExtensibility \ Example.cs :

public class Example
{
    static int val;

    [RepeatTest(5, Timeout=250)]
    public void RepeatingTestMethod()
    {
        Thread.Sleep(100);
        Assert.Equal(2, 2);

        if (val == 0)
        {
            val++;
            Thread.Sleep(1000);
        }
    }
}

Из test.xunit.extensions \ DataTheories \ TheoryAttributeTests.cs :

internal class TestMethodCommandClass
{
    public static IEnumerable<object[]> EmptyData
    {
        get { return new object[0][]; }
    }

    public static IEnumerable<object[]> NullData
    {
        get { return null; }
    }

    public static IEnumerable<object[]> TheoryDataProperty
    {
        get { yield return new object[] { 2 }; }
    }

    [Theory, PropertyData("EmptyData")]
    public void EmptyDataTheory() { }

    [Theory, PropertyData("NullData")]
    public void NullDataTheory() { }

    [Theory, OleDbData(
        @"Provider=Microsoft.Jet.OleDb.4.0; Data Source=DataTheories\UnitTestData.xls; Extended Properties=Excel 8.0",
        "SELECT x, y, z FROM Data")]
    public void TestViaOleDb(double x,
                             string y,
                             string z) { }

    [Theory, PropertyData("TheoryDataProperty")]
    public void TestViaProperty(int x) { }

    [Theory, ExcelData(@"DataTheories\UnitTestData.xls", "SELECT x, y, z FROM Data")]
    public void TestViaXls(double x,
                           string y,
                           string z) { }

}

Подробнее см .:

http://www.codeplex.com/xunit

2 голосов
/ 28 января 2009

монахиня конечно

использование атрибутов было гордостью Кента Бека:

NUnit 2.0 - отличный пример идиоматического дизайна. Большинство людей, которые переносят xUnit, просто транслитерируют версию Smalltalk или Java. Это то, что мы делали с NUnit на первых порах тоже. Эта новая версия NUnit, как это было бы сделано, если бы это было сделано в C # для начала. источник: http://www.nunit.org/

1 голос
/ 04 мая 2009

Castle's ActiveRecord использует атрибуты. Он скрывает некоторую сложность настройки NHibernate, украшая объекты Model атрибутами, указывающими классы и поля, которые должны быть сохранены в базе данных (и как). В компоненте проверки также используются атрибуты для добавления проверки на основе модели в ActiveRecord и стек Monorail .

1 голос
/ 28 января 2009

мы используем пользовательские аннотации Java для обозначения специальных целей определенных методов, в основном предназначенных для разработчиков:

  • @ScriptingAPI - отмечает код, который предоставляется как часть нашего API сценариев (предупреждает разработчиков, что изменения могут повлиять на общедоступный API)
  • @Transaction - отмечает методы на фасаде базы данных, которые запускают / фиксируют транзакцию (у нас есть специальный класс обработчика транзакций, который учитывает эту аннотацию)
  • @NeedsAttentionToSupportFoo - если мы знаем, что функция Foo является требованием, к которому нам нужно будет обратиться в ближайшем будущем, мы используем аннотацию для пометки кода, к которому нам нужно будет прикоснуться, чтобы поддержать его, т.е. когда мы сталкиваемся фрагмент кода, который заставляет нас думать «ах, это нужно изменить, чтобы поддержать Foo», мы комментируем это. если реализация Foo откладывается или никогда не произойдет, проще удалить аннотацию, чем отменить предварительно созданные оптимизации, разбросанные по всему коду.

еще один хороший пример использования пользовательской аннотации описан в этом информационном бюллетене java для специалистов : применение общедоступного конструктора без аргументов во всех подклассах.

1 голос
/ 28 января 2009

Иногда я использую атрибуты для украшения классов или методов и использую отражение для получения «приписанных» данных.

Может быть, это немного сложно объяснить, но последнее, для чего я использовал атрибуты, это система, в которой у меня есть пара сущностей в базе данных.

Каждая сущность имеет своего рода «код», и каждая сущность также может иметь некоторые правила интерпретации.

В моем проекте у меня есть один класс сущностей, который представляет сущность, существующую в базе данных, и у меня также есть набор классов «Правило». Один класс правил содержит логику интерпретации данного объекта.

Чтобы «связать» определенное «Правило» (интерпретацию) с конкретным экземпляром моей сущности, я создал собственный Атрибут.

Я украшаю свой класс «Правило» этим атрибутом, и через атрибут я определяю, для какого объекта это Правило. Затем, когда я загружаю сущность из БД, я вставляю правильное правило в эту сущность.

Немного кода, чтобы прояснить ситуацию:

public class MyEntity
{
    public string Code
    {
       get;
       private set;
    }

    public bool IsValidFor( ... )
    {
        IRule rule = RuleRegistry.GetRuleFor(this);

        if( rule.IsValid() ) ...
    }

}

[RuleAttrib("100")]
public class MyRule : IRule
{
    public bool IsValid()
    {
    }
}

Это всего лишь маленький пример, но я думаю, что вы поймаете дрейф.

Атрибут RuleAttrib в классе MyRule говорит о том, что это правило следует применять к экземпляру MyClass, который имеет код «100».

Экземпляр RuleRegistry может извлечь правильный IRule для текущего объекта (используя отражение).

Другим примером, где я использовал атрибуты в сочетании с Postsharp, является реализация системы «блокировки»: http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html

1 голос
/ 28 января 2009

У меня есть случай, когда я хочу представить фактическую реализацию интерфейса в виде данных. Конечно, это можно сделать с помощью Reflection, но, используя определенный атрибут для членов, которые я хочу представить в качестве данных, я могу инкапсулировать работу, необходимую для этого.

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

...