为什么这个代码编译没有错误,即使该类被标记为已过时?

时间:2011-05-10 20:52:34

标签: c# .net visual-studio-2008 attributes obsolete

这是Visual Studio 2008.显然与扩展的静态类有关。

public class Dummy
{
    public readonly int x;

    public Dummy(int x)
    {
        this.x = x;
    }

    public override string ToString()
    {
        return x.ToString();
    }
}

[Obsolete("Do Not Use", true)]
public static class Extensions
{
    public static int Squared(this Dummy Dummy)
    {
        return Dummy.x * Dummy.x;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var d = new Dummy(42);
        Console.WriteLine(String.Format("{0}^2={1}", d, d.Squared()));
    }
}

5 个答案:

答案 0 :(得分:9)

在VS2010中也是如此。看起来像个bug。我会把它输入数据库。

您可以通过将属性放在实际方法上来解决错误。

感谢您的报告!

答案 1 :(得分:2)

调用过时的函数是警告,而不是错误,除非您将编译器设置更改为停止警告 - 以使警告行为像错误。

除非我的代码中存在其他“真实”错误,否则我通常不会看到这些警告。

另请注意,在您的特定情况下,您将类标记为过时 - 而不是方法。这可能很重要。

答案 2 :(得分:2)

因为它是一个扩展方法,所以你不是直接访问静态类,编译器会生成该代码。

相反,如果您明确访问Squared方法,则会出现编译时错误。

Extensions.Squared(d)

因为这是一个扩展方法,所以只能隐式调用该方法,因此需要将该属性应用于方法本身。

public static class Extensions
{
    [Obsolete("Do Not Use", true)]
    public static int Squared(this Dummy Dummy)
    {
        return Dummy.x * Dummy.x;
    }
}

另一方面,完全删除(或重命名)类将起到相同的作用 - 在这种情况下,您肯定会遇到编译时错误。 :)

修改
您可以向Microsoft here提交错误报告。这似乎应该由编译器处理。

答案 3 :(得分:2)

我认为您发现了编译器错误

虽然扩展方法将被编译为静态方法用法,但似乎编译器不检查它,因为在编译时它以实例方法调用的格式存在


原因在这里。如果我宣布第二种方法:

[Obsolete("Do Not Use", true)]
public static class Extensions
{
    public static int Squared(this Dummy Dummy)
    {
        return Dummy.x * Dummy.x;
    }

    public static int Squared2(Dummy Dummy)
    {
        return Dummy.x * Dummy.x;
    }

}

现在它在第3行抱怨而不是第二行:

class Program
{
    static void Main(string[] args)
    {
        var d = new Dummy(42);
        Console.WriteLine(String.Format("{0}^2={1}", d, d.Squared())); // Fine!?
        Console.WriteLine(String.Format("{0}^2={1}", d, Extensions.Squared2(d))); // COmplains as expected
    }
}

答案 4 :(得分:0)

我认为你需要把属性放在Squared上,而不是类。