Каковы сходства и различия между аннотациями Java и атрибутами C #? - PullRequest
45 голосов
/ 16 февраля 2009

У меня есть библиотека Java, которую я рассматриваю для переноса на C #. Библиотека Java широко использует аннотации (как во время сборки, так и во время выполнения.)

Я никогда не использовал атрибуты C #, но понимаю, что они являются грубым эквивалентом аннотаций Java.

Если я перейду к порту, используя атрибуты для замены аннотаций, что мне нужно знать? Что будет таким же? Разные? Что меня укусит?

Ответы [ 4 ]

25 голосов
/ 17 февраля 2009

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

Java предоставляет аннотацию java.lang.annotation.Retention и java.lang.annotation.RetentionPolicy enum для контроля доступности метаданных аннотации. Выбор может варьироваться от Runtime (наиболее распространенные - метаданные аннотации, сохраняемые в файлах классов) до Source (метаданные, отбрасываемые компилятором). Вы помечаете свой пользовательский интерфейс аннотаций с помощью этого - например:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.CLASS)
public @interface TraceLogging {
  // etc
}

позволит вам поразмышлять о вашей пользовательской аннотации TraceLogging во время выполнения.

C # использует атрибут ConditionalAttribute , который определяется символами времени компиляции. Итак, аналогичный пример в C #:

[Conditional("TRACE")]
public class TraceLoggingAttribute : Attribute
{
  // etc
}

, что заставит компилятор выплевывать метаданные для вашего пользовательского атрибута TraceLogging, только если был определен символ TRACE.

NB. метаданные атрибута доступны во время выполнения по умолчанию в C # - это необходимо, только если вы хотите изменить это.

14 голосов
/ 16 февраля 2009

Один важный аспект аннотаций Java, который я еще не рассматривал подробно: вы можете написать код, который использует аннотации в javac (начиная с Java 6, я считаю) как форму метапрограммирования .

PostSharp допускает нечто подобное, по общему признанию.

(Это далеко не единственная разница, но это все, на что у меня есть время.)

12 голосов
/ 17 февраля 2009

Одно интересное отличие состоит в том, что C # допускает атрибуты уровня модуля и сборки. Они применяются к вашему модулю или сборке и доступны для отражения обычным способом. Java не обеспечивает отражение в файле jar, поэтому аннотации на уровне jar невозможны.

На самом деле это довольно распространенный файл Visual Studio AssemblyInfo.cs на уровне корневого проекта, который, например, содержит

.
[assembly: AssemblyVersionAttribute("1.2.3.4")]
[assembly: AssemblyTitleAttribute("My project name blah blah")]
...

В Java нет эквивалентной аннотации на уровне jar (хотя, начиная с jdk5, существует немного используемый механизм аннотации на уровне пакета - спасибо mmeyers за указание этого)

3 голосов
/ 16 февраля 2009

Следуя тому, что сказал Джон ...

Как Java 5, так и Java 6 допускают метапрограммирование. Java 5 использует отдельный инструмент apt; Java 6 интегрирует его в компилятор. (Хотя Java 5 apt все еще доступна в Java 6)

К сожалению, каждый из них использует свой API.

В настоящее время я использую API Java 5 для своих аннотаций Bean

См. http://code.google.com/p/javadude/wiki/Annotations для примера (ПРИМЕЧАНИЕ. В настоящее время я делаю некоторые важные обновления, некоторые из которых меняют API.)

Очень классные вещи ... - Скотт

...