4

私はこのようなコードを持っています:

public abstract class Base
{
    // is going to be used in deriving classes
    // let's assume foo is threadsafe
    protected static readonly Foo StaticFoo = new Foo();
}

Visual Studio 2008 のコード分析で次のメッセージが表示されます。

CA2104 : Microsoft.Security : Remove the read-only designation from 'Base.StaticFoo' or change the field to one that is an immutable reference type. If the reference type 'Foo' is, in fact, immutable, exclude this message.

私のデザインは本質的に欠陥が[SuppressMessage]ありますか?それともソースに追加できますか?

4

3 に答える 3

8

問題は、間違った印象を与えることです。実際にはオブジェクトではなくフィールド値のみが変更できないのに、値が変更できないように見えます。ここでは、コード分析が過度に慎重になっていると思います.readonlyフィールドに可変型を格納したい場所がたくさんあります.privateで、静的初期化子で初期化され、コード内で決して変更されない場合は特にそうです。

ただし、フィールドは保護されていますが、派生クラスがそれを悪用するリスクが高くなります。個人的には、すべてのフィールドを非公開にするのが好きです。一方で、私はあなたのコードを知りません。可能性と比較検討して、それが正しいことだと判断したのかもしれません。

本当にスレッドセーフである場合Foo、フィールドが読み取り専用であるという事実によって与えられる不変性の一般的な印象を除けば、心配することはあまりありません。その行の警告を無効にし、コメントを追加して、フィールドが読み取り専用であってもオブジェクトが変更可能であることを強調します。

于 2009-03-27T07:37:34.173 に答える
3

Foo 型は不変ですか?

そうでない場合、この 1 つの Foo オブジェクトのみを使用し、そのプロパティを変更できるようにするつもりですか? この場合、警告は単に readonly キーワードが誤解を招くと言っているだけです。コンパイル エラーはありません。オブジェクトへの参照は読み取り専用であり、それがコンパイラに対して宣言されています。ただし、他の開発者に宣言したことは、 StaticFoo は読み取り専用であり、決して変更されないことを意味します。

だから、それが言うように、あなたには選択肢があります。この警告をなくすには、readonly キーワードを削除するか、SuppressMessage 属性を追加します。または、コードの設計を見てください。たとえば、シングルトン パターンとして Foo を実装する方が適切でしょうか?

于 2009-03-27T07:36:06.207 に答える
1

警告は、readonly修飾子が参照自体にのみ適用されることを示しています。Fooが参照型である場合、不変であるFooことを確認しない限り、インスタンスの状態は変更される可能性があります。Foo

別のノードでは、コードの単体テストに関しては、そのような静的があらゆる種類の問題を引き起こす可能性があるため、それが重要な場合は、やろうとしていることを達成するための他の方法を検討することをお勧めします。 .

于 2009-03-27T07:34:24.370 に答える