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

时间:2010-11-05 17:14:42

标签: c#

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

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

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

但显然不会构建。是否有解决方法允许我将此属性应用于setter?

2 个答案:

答案 0 :(得分:12)

我认为这是不可能的,因为由于某种原因,它已被特别禁止使用Obsolete属性。根据围绕属性目标定义的规则,似乎没有任何理由认为Obsolete属性在属性get或set访问器上无效。为了将属性应用于属性集访问器that attribute must be applicable to either a method, parameter, or return value target。如果查看the Obsolete attribute,您会发现“方法”是该属性的有效目标之一。

实际上,您可以使用与过时属性with the AttributeUsage attribute相同的有效目标定义自己的属性,并且您会发现可以将其应用于属性获取或设置访问者,而您无法应用过时属性属性。

[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属性的错误消息是“属性'过时'在属性或事件访问器上无效。”错误消息不同的事实使我相信这是一个规则,无论出于何种原因,显式内置到编译器中的Obsolete属性,而不是依赖于应该被应用于Obsolete属性的AttributeUsage属性。

答案 1 :(得分:7)

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

您可以see this in action在Sharplab上的当前master分支中。它尚未在VS 2019中使用,但将包含在C#8.0的最终版本中。

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

谢谢维利博士的学徒,他指出这与他的回答中的其他属性不一致,并启发了我提出关于罗斯林的问题并实施解决方案。

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