是否可以仅在getter或属性的setter上使用Obsolete属性

wus*_*her 23 c#

是否可以仅在getter或属性的setter上使用Obsolete属性?

我希望能够做到这样的事情:

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

但显然不会建立.有没有解决方法允许我将此属性应用于setter?

Dr.*_*ice 12

我认为这是不可能的,因为由于某种原因,它已被特别禁止用于Obsolete属性.根据围绕属性目标定义的规则,似乎没有任何理由认为Obsolete属性在属性get或set访问器上无效.为了将属性应用于属性集访问器,该属性必须适用于方法,参数或返回值目标.如果查看Obsolete属性,可以看到"method"是该属性的有效目标之一.

实际上,您可以使用与具有AttributeUsage属性的Obsolete属性相同的有效目标来定义自己的属性,并且您将发现可以将其应用于属性get或set访问器,而您不能应用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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您尝试在属性集访问器上创建自己的属性并将其应用于那里,那么您可能会注意到错误消息略有不同.您的自定义属性的错误消息将是"属性'YourCustomAttribute'在此声明类型上无效.",而Obsolete属性的错误消息是"属性'过时'在属性或事件访问器上无效." 错误消息不同这一事实使我相信这是一个规则,无论出于何种原因,显式内置于编译器中的Obsolete属性,而不是依赖于应用于Obsolete属性的AttributeUsage属性. .

  • @Shimmy我不打算从`ObsoleteAttribute`派生一个类,但只是解释了让我相信对Obsolete属性的使用的这种限制是由编译器的实现而不是.NET属性决定的观察结果.使用规则.我不确定为什么课程密封很重要. (2认同)

Yai*_*adt 8

截至2019年4月2日,我的允许将过时属性添加到属性访问器的合并请求已合并到Roslyn(C#编译器)中。

您可以在Sharplab的当前master分支中看到此操作。它尚未在VS 2019中发布,但将包含在C#8.0的最终版本中。

这是C#8.0的功能,因此您必须升级语言版本才能使用它。

感谢Wily博士的学徒,他指出这与他的回答中的其他属性不一致,并激发了我提出关于Roslyn的问题并实施修复方案。

进行这些更改的PR在这里:https : //github.com/dotnet/roslyn/pull/32571

  • @UweKeim。添加到答案 (2认同)