2010-08-04 18 views
6

observar el siguiente código:¿Por qué las estructuras no pueden tener propiedades externas, pero los métodos son correctos?

[AttributeUsage(AttributeTargets.All)] 
public class XAttribute : Attribute 
{ 
} 

public struct A 
{ 
    [X] 
    public static extern int XX { get; } 
} 

Esto no compila. El mensaje de error dice

El modificador 'extern' no es válido para este artículo

embargo, el código siguiente se compila OK:

[AttributeUsage(AttributeTargets.All)] 
public class XAttribute : Attribute 
{ 
} 

public struct A 
{ 
    [X] 
    public static extern int GetXX(); 
} 

Por qué ???

EDITAR

chicos, chicos. No hubiera preguntado si no hubiera tenido una aplicación real para esto. Entiendo que el interés puramente académico de entender por qué algunas cosas se definen tal como son no es algo que nos motive a algunos de nosotros, así que aquí está la motivación realista. Tengo un atributo PostSharp, que inyecta una cierta lógica en la propiedad externa atribuida. Específicamente, el código real se ve así:

[LoggerAccessProperty] 
private static extern ILog Logger { get; } 

Dónde PostSharp procesa el aspecto LoggerAccessProperty e inyecta el método getter real, que las superficies de compilador estático privada generada ejemplo iLog. Esto es parte de nuestra extensión interna del paquete Log4PostSharp. En ese momento, hemos publicado la versión extendida de Log4PostSharp en el sitio de código de Google PostSharp y este atributo es mi última incorporación, pero aún no se ha publicado.

Edit2

Tenga en cuenta, que el código siguiente se compila bien:

[AttributeUsage(AttributeTargets.All)] 
public class XAttribute : Attribute 
{ 
} 

public class A 
{ 
    [X] 
    public static extern int XX { get; } 
} 

La diferencia es que A es una clase aquí, no estructura.

Edit3

estoy usando .NET 4.

+0

La clase compila bien, pero la gran pregunta es ¿realmente se ejecuta? –

+0

Por favor, lea mi primer EDIT de la pregunta. – mark

Respuesta

1

extern propiedades no están permitidos en estructuras.

+3

Una referencia a la especificación de idioma, por favor. – mark

+0

@mark: lo intenté en realidad, no pude encontrarlo. Supongo que fue debido a las reglas Struct más estrictas, pero no lo puse como parte de la respuesta porque no estaba seguro. –

+0

Bueno, entonces esto no es una gran respuesta. Ya sé que no se pueden tener propiedades externas en una estructura, a diferencia de las clases; lo he descubierto por el camino difícil. La pregunta por qué sigue sin respuesta ... – mark

1

El modificador de extern se utiliza para declarar un métodoque se implementa externamente.

La anterior es la primera línea de documentación para la palabra clave extern. (Con énfasis agregado). Dado que solo se aplica a los métodos (no a las propiedades), uno tiene que preguntar: ¿Qué estás tratando de hacer? El hecho de que sea una estructura en lugar de una clase, y la presencia de un atributo en los ejemplos de su código parecen ser pistas falsas.

+0

las propiedades externas están bien en las clases. –

+0

@Yuriy Faktorovich: por favor proporcione un código de muestra de trabajo. Dudo que CLR lo implemente de ninguna forma. – leppie

+0

Por supuesto, la pregunta sigue siendo 'por qué'. Las propiedades en última instancia son solo métodos, compilados como get_XXX y set_XXX. Entonces, ¿por qué no les permiten ser 'externos'? –

0

Dado que una declaración de método externo no proporciona una implementación real, hay sin cuerpo de método; la declaración del método simplemente termina con un punto y coma y no hay llaves ({}) después de la firma.

Así que si ha cambiado su código a:

[LoggerAccessProperty] 
private static extern ILog Logger(); 

que debería funcionar bien en su estructura.

Reference Link

+0

Sin embargo, la propiedad externa compila muy bien para las clases. Su respuesta no explica ni indica ninguna diferencia entre la estructura y la clase con respecto a las propiedades externas, mientras que existe y quiero saber por qué. – mark

+0

Su pregunta anterior muestra dos estucos (no veo mención de estructura frente a clase). No hay diferencia entre el manejo de externos en estructuras vs clases. Simplemente no puede tener una propiedad externa, porque un externo no tiene cuerpo de método. Una propiedad (en cualquier forma) tiene un cuerpo de método (IE: {get; set;} o uno) que lo hace inválido para ser usado con extern. En cuanto a la parte de compilación, eso es bastante extraño. –

+0

También podría ser bueno saber qué versión del marco está utilizando. Ayudaría a encontrar la documentación correcta. Solo digo. –

0

Parece que un error en el compilador (que no va a ser fijo). El descriptor de acceso a la propiedad se compila en los métodos en JSIL, por lo que puede usar el método get_XXX.

Cuestiones relacionadas