使用 属性 访问器的过时成员字段(Visual Studio 错误)

Obsolete member field with property accessor (Visual Studio bug)

我有一个 class 有一个成员,我需要为遗留代码保留它,我需要将它标记为过时,这样新代码就不会使用它(没有收到警告)。

假设 class 看起来像这样:

class MyClass
{
    [Obsolete]
    private string _old = "...";

    [Obsolete]
    public string Old
    {
        get { return _old; }
    }
}

我声明成员字段 _old 已过时,以确保 class 中的新 代码不使用该字段。

我还声明 属性 Old 已过时,以确保 class 之外的 代码不使用属性.

当我编译它时,我在 属性 getter 中收到一条警告,说 _old 已过时。我认为编译器会默默地忽略它,因为 属性 本身已经过时了。

我是不是漏掉了什么,或者我是否需要为过时的成员字段添加 #pragma warning disable/restore(即使 method/property 本身被标记为过时)?


我认为编译器会默默地忽略这个”的原因是因为它似乎对过时的 classes:

[Obsolete]
public class MyObsoleteClass
{
    public string DoSomething()
    {
        // No warning here, since the class itself is obsolete
        return new MyClass().Old;
    }
}

正如@Heinzi 回答的那样:这似乎是由于 Visual Studio 中的一个错误。我已提交有关连接的报告:

https://connect.microsoft.com/VisualStudio/feedback/details/1146809


事实证明 Visual Studio 中的错误不仅限于从 属性.

访问过时的字段

从过时的方法访问过时的 属性 不应产生警告:

public class Class2
{
    [Obsolete]
    public string Property { get; set; }

    [Obsolete]
    public void Method()
    {
        this.Property = "value"; // <-- Incorrect warning reported
    }
}

也不应该从另一个人那里这样做 class:

public class Class3
{
    [Obsolete]
    public string Property { get; set; }
}

public class Class4
{
    [Obsolete]
    public string Method()
    {
        return new Class3().Property; // <-- Incorrect warning reported
    }
}

有趣的是,它在下面的 class 中起作用,当添加这个 class 时,其他警告(来自 Class4Class2)将神奇地消失。

public class Class5
{
    [Obsolete]
    public void Method()
    {
        // No warning reported here, which is good.
        // This magically makes the other warnings disappear too!
        new Class2().Method();
    }
}

你的代码很好,你对 Obsolete 属性应该如何工作的理解是正确的:如果你在编译后查看 "Output" 选项卡,你会注意到 编译器 不会针对您的情况输出警告(但是如果您从 属性 中删除 Obsolete 属性, 输出警告,因为预期)。

不过,您是对的,Visual Studio 有时会在对代码进行任意更改后显示警告。这似乎是 Visual Studio 中的错误。如果您仍然可以使用最新版本重现它,我建议您在 http://connect.microsoft.com.

上提交错误报告

这将是一个聪明的功能,但我没有在文档中看到任何迹象表明它应该以这种方式工作。另一方面,我不会在私有成员上使用 Obsolate 属性(如果 class 不是非常大),但我会重构它。我会这样写:

class MyClass
{
    [Obsolete]
    public string Old
    {
        get; private set;
    }
}

然后你只需要将_old的用法改成Old就可以解决问题了