15

This is Visual Studio 2008. Obviously has to do with the static class for an extensions.

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()));
    }
}
Cade Roux
  • 88,164
  • 40
  • 182
  • 265

5 Answers5

9

That repros in VS2010 as well. Looks like a bug. I'll get it entered in the database.

You can work around the bug by putting the attribute on the actual method.

Thanks for the report!

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
2

Calling an obsolete function is a warning, not an error, unless you change the compiler settings to stop on warnings too - to make warnings behave like errors.

Typically I don't see those warnings unless there are other 'real' errors in my code.

Also notice that in your specific case you marked the class as obsolete - not the method. That might matter.

n8wrl
  • 19,439
  • 4
  • 63
  • 103
2

Because it's an extension method, you are not directly accessing the static class, the compiler generates that code.

If, instead, you accessed the Squared method explicitly, you would get the compile-time error.

Extensions.Squared(d)

Since this is an extension method, however, you only implicitly invoke the method, so the attribute will need to be applied to the method itself.

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

On the other hand, deleting (or renaming) the class altogether would serve the same purpose - you will definitely get a compile-time error in that case. :)

EDIT
You can file a bug report with Microsoft here. This seems like behavior that should be handled by the compiler.

Ryan Emerle
  • 15,461
  • 8
  • 52
  • 69
  • 1
    That's not to say that it wouldn't be nice if the compiler supported the `Obsolete` attribute on static classes for extension methods. – Ryan Emerle May 10 '11 at 21:05
  • It's kind of scary, because you might assume that something marked Obsolete/True could be removed (other Obsolete/True things which are in unused code paths may also have to be removed, and I guess this may be considered a subtle variation on that). – Cade Roux May 10 '11 at 21:08
  • You can certainly have a non-static class marked obsolete/true which has other obsolete/true things depending on it and it will compile without error as long as that whole part of the object model is orphaned. – Cade Roux May 10 '11 at 21:22
2

I think You have found a compiler bug:

Although the extension method will be compiled to the static method usage, it seems the compiler does not check it since at the time of compilation it exists in the format of instance method call.


Reason is here. If I declare a second method:

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

}

Now it complains at the 3rd line not second:

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
    }
}
Aliostad
  • 80,612
  • 21
  • 160
  • 208
0

I think you need to put the attribute on Squared, not the class.

Lou Franco
  • 87,846
  • 14
  • 132
  • 192
  • No. It has `AttributeUsage.Class` defined against it. – Aliostad May 10 '11 at 20:58
  • On non-static classes, a class can be marked obsolete without having to mark anything else obsolete. I understand that a static class is not at all really like a non-static class, but it seemed odd that it didn't give any warning that the attribute is invalid at that level. – Cade Roux May 10 '11 at 21:03
  • It's valid with a static class, put any non-extension function in there and try to call it and it will throw an error. The extension function just escapes the notice of the attribute on the static class because it's not really part of the Extensions class rather its part of the Dummy class. – Felan May 10 '11 at 21:11
  • 1
    @Felan, In Ryan's answer and Aliostad's example, it appears that sometimes it can be considered a part of that obsolete class if it's accessed explicitly. So it's kind of schizoid. – Cade Roux May 10 '11 at 21:15