Почему этот код компилируется без ошибок, даже если класс помечен как Obsoleted?

Это 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()));
    }
}

Ответы

Ответ 1

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

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

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

Ответ 2

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

Обычно я не вижу этих предупреждений, если в моем коде нет других "реальных" ошибок.

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

Ответ 3

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

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

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

ИЗМЕНИТЬ
Вы можете отправить отчет об ошибке с помощью здесь. Это похоже на поведение, которое должен выполнять компилятор.

Ответ 4

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

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


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

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

}

Теперь он жалуется на третьей строке не второй:

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

Ответ 5

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