7

C# では、"スマートな" 列挙型を作成したいと考えています。Java では、基になる int 値だけでなく、列挙型値に関連付けられた情報が多くあるようなものです。次の簡単な例のように、(列挙型の代わりに)クラスを作成するスキームに出くわしました。

public sealed class C
{
    public static readonly C C1 = new C(0, 1);
    public static readonly C C2 = new C(2, 3);

    private readonly int x;
    private readonly int y;

    private C(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int X
    {
        get
        {
            return this.x;
        }
    }

    public int Y
    {
        get
        {
            return this.y;
        }
    }
}

しかし、その上で Visual Studio の「コード アナライザー」を実行すると、警告 C2104、「読み取り専用の変更可能な参照型を宣言しないでください」が表示されます。

一般に、読み取り専用の可変参照型を宣言したくない理由はわかりますが、... 私のクラスは可変ではありませんか?

警告のドキュメントを読むと、読み取り専用の参照型は変更可能であると想定しているようです。たとえば、型が本当に不変である場合は、この警告を抑制してもかまいません。実際、次のさらに単純なクラスについても同じ警告が表示されます。

public sealed class C
{
    public static readonly C C1 = new C();
    public static readonly C C2 = new C();

    private C()
    {
    }
}

私が可変性を真剣に誤解していない限り、CA2104 はそれを理解していません。そして、クラスが本当に不変であると確信している限り、警告が表示される各行の警告を抑制することをお勧めします。しかし:

(1) したがって、このチェックを完全にオフにしない限り、不変の読み取り専用メンバーを使用するたびにチェックを抑制しなければなりません。

(2) さらに悪いことに、私がそれを行ったとしても、後で誰かが誤って可変性を導入する可能性がありますが、他の誰かは、「私がチェックし、これは不変です」と言って手動で抑制を入れたという事実によって与えられた誤った安心感をまだ持っています。 "?

4

1 に答える 1

5

その通りです。これは、このシナリオでは誤検知です。唯一の選択肢は、個別に抑制するか、警告をオフにすることです。欠点は、各オプションについて説明したとおりです。

この警告を回避するためのその他のオプションには、次のものがあります。

  • 静的フィールドを使用しないでください。代わりに、public get および private セットで静的プロパティを使用し、インラインではなくコンストラクターで初期化することができます。

  • これらの不変の値の型を作成します。これにより、警告が回避されますが、シナリオによっては異なる動作が発生する可能性があります。これは、場合によってはオプションである場合とそうでない場合があります。

于 2013-05-04T21:44:49.360 に答える