Подтвердить что ты не робот

Можно ли использовать атрибут Obsolete только для получателя или сеттера свойства

Можно ли использовать атрибут Obsolete только для getter или setter свойства?

Я хотел бы сделать что-то вроде этого:

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

но, очевидно, это не будет построено. Есть ли работа, которая позволяет мне применить этот атрибут только к установщику?

4b9b3361

Ответ 1

Я думаю, что это невозможно, потому что по какой-то причине он был специально запрещен для атрибута Obsolete. Согласно правилам, определенным вокруг целевых объектов атрибута, нет никакой причины, что атрибут Obsolete недействителен для свойства get или set accessor. Чтобы применить атрибут к аксессуру набора свойств, этот атрибут должен быть применим к цели метода, параметра или возвращаемого значения. Если вы посмотрите на атрибут Obsolete, вы увидите, что "метод" является одной из допустимых целей для этого атрибута.

Фактически вы можете определить свой собственный атрибут с теми же действительными целями, что и атрибут Obsolete с атрибутом AttributeUsage, и вы обнаружите, что можете применить его для свойства get или set accessor, тогда как вы не можете применить атрибут Obsolete.

[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; }
    }
}

Если вы попытаетесь создать свой собственный атрибут, который недействителен в аксессуре набора свойств, и вы примените его там, вы можете заметить, что сообщение об ошибке несколько отличается. Сообщение об ошибке для вашего настраиваемого атрибута будет "Атрибут" YourCustomAttribute "недействителен для этого типа объявления.", Тогда как сообщение об ошибке для атрибута Obsolete "Attribute" Obsolete "недействительно для аксессуаров свойств или событий". Тот факт, что сообщение об ошибке отличается, заставляет меня поверить, что это правило, которое по какой-либо причине явно встроено в компилятор для атрибута Obsolete, вместо того, чтобы полагаться на атрибут AttributeUsage, который, предположительно, применяется к атрибуту Obsolete.

Ответ 2

У меня была такая же проблема сегодня, и у меня было решение, которое работало для простых объектов данных, которые не имеют никакой логики. Вместо того, чтобы сделать сеттер устаревшим (который не работает по причинам, указанным в другом ответе), я сделал сам конструктор устаревшим и представил новый, где я предоставляю начальное значение. Это предполагает, что конструктор по умолчанию был запущен для создания экземпляра класса. Возможно, вам стоит отметить еще один.

Однако мы не можем использовать автоматически реализованные свойства в этом случае, чтобы иметь возможность установить начальное значение внутри конструктора:

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; }
    }
}

Таким образом, я создал свойство readonly, значение которого может быть задано только конструктором. Любой attemp для создания экземпляра его конструктором по умолчанию и для установки его свойства не выдает предупреждения компилятора для установщика, а для экземпляра - что в моем случае нормально:

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

Имейте в виду, что это не работает, если ваше свойство не предназначено для установки снаружи вообще. Это когда его значение вычисляется в вашем новом коде:

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