web-dev-qa-db-ja.com

JavaアノテーションとC#属性の類似点と相違点は何ですか?

C#への移植を検討しているJavaライブラリがあります。Javaライブラリは、ビルド時と実行時の両方でアノテーションを広範囲に使用します。)

私はC#属性を使用したことがありませんが、それらがJavaアノテーションとほぼ同等であることを理解しています。

属性を使用してアノテーションを置き換えるポートを続行する場合、何を知る必要がありますか?何が同じになるのでしょうか?違いますか?何が私を噛むのだろうか?

45
Jared

メタデータにアクセスできるようにするタイミングの制御は、2つの言語間で異なります。

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#ではデフォルトで実行時に使用できます。これは、変更する場合にのみ必要です。

25
serg10

Javaアノテーションについては、まだ詳しく説明していません。Javac内でアノテーションを使用するコードを記述できます(Java 6、私は信じています) メタプログラミングの一形態として

PostSharp 確かに、同様のことを許可します。

(それが唯一の違いではありませんが、今のところ時間があるのはそれだけです。)

14
Jon Skeet

1つの興味深い違いは、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 それを指摘してくれました)

12
serg10

ジョンが言ったことに続いて...

Java 5とJava 6はメタプログラミングを許可します。Java 5は別のaptツールを使用します; Java 6はそれをコンパイラに統合します(ただし、Java 5aptはJava 6)で引き続き使用できます)

残念ながら、それぞれが異なるAPIを使用しています。

現在、BeanアノテーションにJava 5APIを使用しています

例については、 http://code.google.com/p/javadude/wiki/Annotations を参照してください(注:現在、いくつかのメジャーアップデートを行っており、その一部はAPIを変更しています)。

とてもかっこいいもの...-スコット

3