2009-02-16 27 views
38

Tengo una biblioteca Java que estoy considerando transferir a C#. La biblioteca Java hace uso extensivo de anotaciones (tanto en tiempo de compilación como en tiempo de ejecución).¿Cuáles son las similitudes y diferencias entre las anotaciones Java y los atributos C#?

Nunca he usado atributos C#, pero entiendo que son el equivalente aproximado de las anotaciones Java.

Si procedo con el puerto utilizando los atributos para reemplazar las anotaciones, ¿qué debo saber? ¿Qué va a ser lo mismo? ¿Diferente? ¿Qué me va a morder?

Respuesta

13

Un aspecto importante de las anotaciones de Java que aún no he analizado en detalle: puede escribir código que utiliza anotaciones dentro de javac (a partir de Java 6, creo) as a form of metaprogramming.

PostSharp permite algo similar, hay que admitirlo.

(Eso es lejos de ser la única diferencia, pero es todo lo que tengo tiempo para este momento.)

+0

Aunque he visto apt, en realidad no uso la API APT; mi código usa reflexión (y un doclet) para hacer su trabajo (en lugar de usar APT para generar un conjunto de elementos intermedios durante la compilación) .) Por lo tanto, creo que no estoy preocupado por esta capacidad faltante. Sigan viniendo :) – Jared

+0

Jon - solo hace un clic para avisar que hay una recompensa de 100 puntos en esta pregunta - si tiene más tiempo para pasar dando una respuesta más completa (y los puntos valen la pena) - Me gustaría ciertamente bienvenido :) ¡Gracias! – Jared

+2

Sí, como Jon realmente necesita esa recompensa de 100 puntos :) – ArielBH

2

En seguimiento a lo que dijo Jon ...

Tanto Java 5 y Java 6 permitirá metaprogramming. Java 5 usa una herramienta apt por separado; Java 6 lo integra en el compilador. (Aunque el Java 5 apt todavía está disponible en Java 6)

Desafortunadamente cada uno usa una API diferente.

Actualmente estoy usando la API de Java 5 para mis anotaciones de frijol

Ver http://code.google.com/p/javadude/wiki/Annotations para un ejemplo (NOTA: Actualmente estoy haciendo algunos cambios importantes, algunos de los cuales cambian la API.)

Cosas muy interesantes ... - Scott

9

Una diferencia interesante es que C# permite atributos de módulo y nivel de ensamblaje. Estos se aplican a su módulo o conjunto y están disponibles a través de la reflexión de la manera normal. Java no proporciona una reflexión en un archivo jar, por lo que las anotaciones de nivel de jar no son posibles.

De hecho esto es bastante común como Visual Studio un archivo llamado AssemblyInfo.cs a nivel de proyecto raíz que contiene, por ejemplo:

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

No hay ninguna anotación nivel frasco equivalente en Java (aunque desde JDK5, hay es un pequeño mecanismo de anotación de nivel de paquete usado - gracias a mmeyers para señalarlo)

+1

+1. Interesante. Gracias. – Jared

+3

En realidad, hay anotaciones a nivel de paquete en Java: ver http://java.sun.com/docs/books/jls/third_edition/html/packages .html # 97373. –

+0

buena llamada - Me olvidé por completo de package-info.java – serg10

21

El control sobre cuándo se hacen accesibles sus metadatos es diferente entre los dos idiomas.

Java proporciona la java.lang.annotation.Retention anotación y java.lang.annotation.RetentionPolicy enumeración para controlar cuándo metadatos anotación es accesible. Las opciones varían desde Runtime (más común: metadatos de anotación conservados en archivos de clase), hasta Source (metadatos descartados por el compilador). Etiquetar su interfaz de anotación personalizada con esto - por ejemplo:

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

permitiría a reflexionar sobre su encargo TraceLogging anotación en tiempo de ejecución.

C# utiliza el atributo ConditionalAttribute que se controla a partir de los símbolos de tiempo de compilación. Así que el ejemplo análogo en C# es:

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

que haría que el compilador para escupir los metadatos personalizados para su TraceLogging atributo sólo si se define el símbolo TRACE.

NB. los metadatos de atributo están disponibles en tiempo de ejecución de forma predeterminada en C#; esto solo es necesario si desea cambiar eso.

+3

+1: Retención en el tiempo de ejecución será importante para el puerto. Gracias. – Jared

+1

yw. Tenga en cuenta que según mi última edición, podrá reflejar su atributo C# personalizado si no hace nada. Este mecanismo le permite desactivar ese comportamiento predeterminado, que es probablemente de utilidad limitada para ser honesto. – serg10

Cuestiones relacionadas