Почему этот код компилируется без ошибок, даже если класс помечен как устаревший? - PullRequest
15 голосов
/ 11 мая 2011

Это 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 ]

9 голосов
/ 11 мая 2011

Это также в VS2010.Похоже на ошибку.Я внесу его в базу данных.

Вы можете обойти ошибку, поместив атрибут в метод.

Спасибо за отчет!

2 голосов
/ 11 мая 2011

Я думаю Вы обнаружили ошибку компилятора :

Хотя метод расширения будет скомпилирован для использования статического метода, похоже, компилятор не проверяетэто , так как на момент компиляции он существует в формате вызова метода экземпляра .


Причина здесь.Если я объявлю второй метод:

[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
    }
}
2 голосов
/ 11 мая 2011

Поскольку это метод расширения, у вас нет прямого доступа к статическому классу, компилятор генерирует этот код.

Если вместо этого вы обратились к методу 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;
    }
}

С другой стороны, удаление (или переименование) класса в целом будет служить той же цели - в этом случае вы обязательно получите ошибку времени компиляции. :)

EDIT
Вы можете отправить сообщение об ошибке в Microsoft здесь . Это похоже на поведение, которое должно обрабатываться компилятором.

2 голосов
/ 11 мая 2011

Вызов устаревшей функции является предупреждением, а не ошибкой, если вы не измените настройки компилятора, чтобы также останавливать предупреждения - чтобы предупреждения вели себя как ошибки.

Как правило, эти предупреждения не отображаются, если нетдругие «реальные» ошибки в моем коде.

Также обратите внимание, что в вашем конкретном случае вы пометили класс как устаревший, а не метод.Это может иметь значение.

0 голосов
/ 11 мая 2011

Я думаю, вам нужно поместить атрибут в квадрат, а не в класс.

...