xin9le.net

Microsoft の製品/技術が大好きな Microsoft MVP な管理人の技術ブログです。

using staticするとObsoleteが警告されない

Obsolete 属性、使ってますか?「もう古い API だから使わないでねー」とコンパイラ警告を出すて注意喚起するための便利属性です。以下のように利用します。

class Program
{
    [Obsolete("NewMethod を利用してください")]
    public static void OldMethod(){ ... }
    public static void NewMethod(){ ... }
    static void Main()
    {
        OldMethod();
    }
}

//--- CS0618 : 'Program.OldMethod()' is obsolete: 'NewMethodを利用してください'

警告が出ないケース

Visual Studio 2015 CTP 5 + C# 6.0 で遊んでいたら、本記事のタイトル通り、警告が出ないケースに遭遇しました。簡単なサンプルは以下の通りです。

using System;
using static System.Console;
using static CSharpVNext.Fruits;  //--- ここに型名を書いていても警告されない

namespace CSharpVNext
{
    [Obsolete]
    enum Fruits
    {
        Apple,
        [Obsolete] Banana,
    }

    class Program
    {
        static void Main()
        {
            WriteLine(Apple);  //--- 型名を省略しているので警告が出ない
            WriteLine(Banana); //--- Banana 自体に Obsolete があるので警告が出る
        }
    }
}

//--- CS0618 : 'Fruits.Banana' is obsolete

Obsolete 属性は注意喚起のためだと思っていたので、これを掻い潜るパスがあるのは良いのかどうか...(うーん

[追記] using エイリアスでも同じ挙動

ふと「using エイリアスはどうなんだろう?」と思って試してみたら、先の挙動と同じでした。Obsolete 属性によるコンパイラ警告で、その利用箇所を全てを知らせることは難しそう。

using System;
using static System.Console;
using F = CSharpVNext.Fruits;  //--- ここに型名を書いていても警告されない

namespace CSharpVNext
{
    [Obsolete]
    enum Fruits
    {
        Apple,
        [Obsolete] Banana,
    }

    class Program
    {
        static void Main()
        {
            WriteLine(F.Apple);  //--- エイリアス名では警告が出ない
            WriteLine(F.Banana); //--- Banana 自体に Obsolete があるので警告が出る
        }
    }
}