50

I have a Java library I'm considering porting to C#. The Java library makes extensive use of annotations (at both build time and run time.)

I've never used C# attributes, but understand that they are the rough equivalent of Java annotations.

If I proceed with the port using attributes to replace annotations, what do I need to know? What's going to be the same? Different? What's going to bite me?

4

4 回答 4

30

两种语言对何时可访问元数据的控制是不同的。

Java 提供java.lang.annotation.Retention注解和java.lang.annotation.RetentionPolicy枚举来控制注解元数据何时可访问。选择从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

注意。默认情况下,属性元数据在 C# 中在运行时可用 - 仅当您想更改它时才需要。

于 2009-02-17T13:31:47.553 回答
18

Java 注释的一个重要方面我还没有详细研究过:您可以编写在 javac 中使用注释的代码(我相信从 Java 6 开始)作为元编程的一种形式

诚然, PostSharp允许类似的东西。

(这远不是唯一的区别,但这是我现在有时间的全部。)

于 2009-02-16T16:32:34.587 回答
15

一个有趣的区别是 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指出这一点)

于 2009-02-17T13:06:43.807 回答
3

按照乔恩所说的...

Java 5 和 Java 6 都允许元编程。Java 5 使用单独的 apt 工具;Java 6 将其集成到编译器中。(虽然 Java 5 apt 在 Java 6 中仍然可用)

不幸的是,每个都使用不同的 API。

我目前正在为我的 Bean 注释使用 Java 5 API

有关示例,请参见http://code.google.com/p/javadude/wiki/Annotations(注意:我目前正在进行一些重大更新,其中一些更改了 API。)

非常酷的东西……——斯科特

于 2009-02-16T19:27:02.233 回答