2010-05-12 12 views
7

Considere este escenario:¿Cómo y por qué se desaconseja ObsoleteAttribued para los descriptores de acceso a propiedades?

public class C 
{ 
    private int _foo; 

    public int Foo 
    { 
     get { return _foo; } 

     [Obsolete("Modifying Foo through the setter may corrupt hash tables. " 
      + "Consider using the method 'ModifyFoo' instead.")] 
     set { _foo = value; } 
    } 

    public C ModifyFoo(int foo) 
    { 
     // return a new instance of C 
    } 
} 

cual no quiere compilar: CS1667

error: Atributo 'obsoleto' no es válido en la propiedad o descriptores de acceso de eventos. Solo es válido en las declaraciones 'class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate'.

atributos específicamente que se aplican a los descriptores de acceso es perfectamente bien para cualquier otro atributo (siempre que AttributeTargets.Method está configurado en sus usos, lo cual es cierto para ObsoleteAttribute).

Respuesta

7

Claramente es el compilador que prohíbe explícitamente su uso, no es por accidente. Hmya, ¿por qué? Una solución para una restricción en el compilador parece bastante improbable. Supongo que decidieron prohibirlo para evitar confusiones al programador que recibe la advertencia. A menos que el mensaje esté bien elaborado, sería bastante confuso que se muestre de manera irregular, dependiendo del uso de la propiedad.

+1

Me pregunto si los compiladores para otros lenguajes .NET lo permiten, y qué pasaría si su código C# hace referencia a un ensamblado donde se configuró. – Tinister

+1

Interesante comentario. Intenté con VB.NET que permite '' en un setter. Resultado inesperado: el getter se vuelve obsoleto también. Ahora grazna como una restricción de compilación. –

+0

Además, C# los tratará como advertencias y no como errores, incluso si el atributo en VB.NET está establecido en IsError = true, lo que le permite seguir creando código nuevo utilizando el setter marcado ObsoleteAttribute – Seph

1

En este caso, si fuera a hacerlo obsoleto, ¿no podría simplemente no incluirlo? El objetivo de la bandera obsoleta es decir que hay una manera diferente (y mejor de hacer algo).

En este caso, es probable que desee hacer que el cambio sea un cambio radical y obligue a las personas a actualizar el código.

+1

Que es lo que hice. Solo tengo curiosidad sobre por qué es esto. – Tinister

1

¿Por qué no modifica la propiedad para usar el código en ModifyFoo?

+0

Los establecedores de propiedades tienen un tipo de devolución de nulo. 'ModifyFoo' devuelve una nueva instancia de C. – Tinister

+0

Correcto. Las personas que llaman pueden llamar a 'ModifyFoo' sin un argumento de retorno, y puedes eliminar al setter. O bien, ejecute una excepción en el colocador que devuelve el mensaje "Use ModifyFoo para establecer esto". (No es la mejor solución, pero si no quieres un cambio radical ...) –

+0

Pareces malinterpretar, que es mi culpa por los nombres pobres en mi escenario publicado. El punto es hacer cumplir la inmutabilidad. 'c.Foo = 10; c.ModifyFoo (15); 'no va a cambiar el valor de' c.Foo', que seguirá siendo 10. 'c.Foo = 10; c = c.ModifyFoo (15); '_will_ change' c.Foo', ya que estoy reasignando 'c'. – Tinister

Cuestiones relacionadas