2010-11-05 9 views
18

¿Es posible utilizar el atributo obsoleto solamente un captador o un regulador de una propiedad?¿Es posible utilizar el atributo obsoleto solamente un captador o un regulador de una propiedad

Me gustaría ser capaz de hacer algo como esto:

public int Id { 
    get { return _id;} 
    [Obsolete("Going forward, this property is readonly",true)] 
    set { _id = value;} 
} 

pero obviamente eso no va a construir. ¿Hay algún trabajo que me permita aplicar este atributo solo al colocador?

+1

Puesto que usted ha establecido que para elevar errores, ¿por qué no eliminar la incubadora, van a ser notificada se lee solamente. – Doggett

+1

Todavía se puede desactivar el error utilizando la directiva #pragma warning' ', a pesar de que no es sólo una advertencia. De esta forma, el código heredado seguirá generando, mientras que el código futuro no se generará. –

Respuesta

9

creo que esto no se puede hacer porque, por alguna razón, se ha anulado específicamente para el atributo obsoleto. De acuerdo con las reglas definidas en torno a los objetivos de los atributos, no parece haber ninguna razón para que el atributo Obsoleto no sea válido en un acceso de obtención o configuración de propiedades. Para aplicar un atributo a un descriptor de acceso del conjunto de propiedades, that attribute must be applicable to either a method, parameter, or return value target. Si mira the Obsolete attribute, puede ver que el "método" es uno de los objetivos válidos para ese atributo.

De hecho, puede definir su propio atributo con los mismos objetivos válidos que el atributo Obsoleto with the AttributeUsage attribute, y encontrará que puede aplicarlo a un acceso de propiedad obtener o establecer mientras que no puede aplicar el atributo Obsoleto.

[AttributeUsage(AttributeTargets.Method)] 
class MyMethodAttribute : Attribute { } 

class MyClass 
{ 
    private int _Id; 

    public int Id 
    { 
     get { return _Id; } 

     [MyMethodAttribute] // this works because "Method" is a valid target for this attribute 
     [Obsolete] // this does not work, even though "Method" is a valid target for the Obsolete attribute 
     set { _Id = value; } 
    } 
} 

Si intenta crear su propio atributo que no es válido en un método de acceso de propiedad y de aplicarlo allí, entonces es posible que observe el mensaje de error es ligeramente diferente. El mensaje de error para el atributo personalizado será "Atributo 'YourCustomAttribute' no es válido en este tipo de declaración.", Mientras que el mensaje de error para el atributo obsoleto es "Atributo 'obsoleto' no es válido en la propiedad o descriptores de acceso de eventos." El hecho de que el mensaje de error sea diferente me hace creer que esta es una regla explícitamente incorporada en el compilador para el atributo Obsoleto, en lugar de confiar en el atributo AttributeUsage que, supuestamente, se aplica al atributo Obsoleto. .

+0

El 'ObsoletteAttribute' está' sellado' ... – Shimmy

+1

@Shimmy No estaba sugiriendo derivar una clase de 'ObsoleteAttribute', pero solo estaba explicando las observaciones que me llevan a creer que esta restricción en el uso del atributo obsoleto está determinada por la implementación del compilador, no por las reglas de uso de atributos .NET. No estoy seguro de por qué importa el hecho de que la clase sea sellada. –

+0

@ Dr.Willy, lo extrañé, lo siento ... Tengo una propiedad Necesito que sea de lectura y escritura, pero no quiero que se use la escritura, solo necesito cumplir un requisito del contrato, el 'ObsoleteAttribute' podría ser útil aquí. – Shimmy

0

Tuve el mismo problema hoy y tuve una solución que funcionaba para objetos de datos simples que no tienen lógica propia. En lugar de hacer que el setter sea obsoleto (lo cual no funciona por las razones mencionadas en otra respuesta), hice el constructor mismo obsoleto e introduje uno nuevo donde proporciono el valor inicial. Esto supone que el constructor predeterminado se ejecutó para crear la instancia de la clase. Tal vez tendrías que marcar a otro.

Sin embargo, no puede utilizar las propiedades de auto-aplicado en este caso con el fin de ser capaz de establecer el valor inicial dentro del constructor:

class MyClass 
{ 
    [Obsolete("Use the constructor with param myProperty instead")] MyClass() { } 
    MyClass(MyProperty m) { this.m_MyProperty = m; } 

    public MyType MyProperty 
    { 
     get { return this.m_MyProperty; } 
     set { this.m_MyProperty = value; } 
    } 
} 

Así que, de hecho, he creado un solo lectura-propiedad cuyo valor puede solo ser establecido por el constructor. De cualquier intento de crear una instancia por su default-constructor y para establecer su propiedad no producirá el compilador de alerta para el organismo pero para la creación de instancias - que está bien en mi caso:

var m = new MyClass(); // here we get warning/error now 
m.MyProperty = 

Tenga en cuenta que este doesn el 't trabajo si su ment NO ES propiedad para ajustar desde el exterior en absoluto. Esto es cuando su valor se calcula en el nuevo código:

MyProperty { get { return /* some computation */ } } 
Cuestiones relacionadas