0

これはばかげた間違いです:

List<Foo> fooList = new List<Foo>();
Foo f = new Foo();
while (something.Read()) {
    f.Fill(something.GetRecord());
    fooList.Add(f);
}

もちろん、ループ内で新しいFooをインスタンス化する必要があります。

コンパイラはコンパイル時にこの種の間違いを検出できますか?

素朴な目には、この動作を検出できるはずです(ループ内の同じオブジェクトのインスタンスでリストを埋める)。次に、「同じインスタンスでコンテナを複数回満たしています。」などの警告を発行する必要があります。

それで、私はどれほど素朴ですか?このようなものが存在する言語を知っていますか?

4

2 に答える 2

2

List <>をオブジェクトの複数のインスタンスで埋めたい場合はどうなりますか?#pragmaコンパイラがあなたを放っておくように、コードを装飾する必要がありますか?

この種の制限があるクラスをどのように宣言しますか?List <>は実際にはC#クラスにすぎません。mscorlib.dllを逆コンパイルして、その完全な実装を確認できます。したがって、この種の知識を得るには、どこかにハードコーディングする必要があります。属性?それは信じられないほど制限されます。コードを検証するための特別な方法はありますか?オブジェクトにオーバーヘッドが追加されます。

この種のものは、理由のために決して使用されません(そして私は決して使用されません):それが妨げるのではなく役立つという非常に少数のケースは、(フレームワーク自体とコードの)およびパフォーマンスのヒット(GCが実行するときにメモリ内を移動する必要がある肥大化したオブジェクトから)。

于 2009-09-23T12:06:44.850 に答える
2

はい、これは可能です。

ただし、ツールやコンパイラがこれについて警告することはないと思います。そのため、独自の分析で拡張できるツールを使用する必要があります。Javaの場合、FindBugsはそのようなツールです。C、C ++などの場合、gcc 4.5を使用すると、プラグインで独自の拡張機能を作成できます。LLVMのclangもこのために設計されています。また、C++用のMozillaのDehydraもあります。MS言語には、Phoenixフレームワークがあります。

問題は、この分析をどのように書くかということです。これはもう少し注意が必要で、ツールによって異なります。しかし基本的に:

  • ループをかなり簡単に検出できます(「強く接続されたコンポーネント」を探してください)。
  • エイリアス解析では、特定の変数またはパラメーターが1つのオブジェクトのみを参照しているか、多数のオブジェクトを参照しているかを知ることができます(おそらく「抽象オブジェクト」を探してください)。
  • オブジェクトまたは変数の静的タイプを使用して、適切なコンテナーを見つけることができます。

したがって、ループ内のへの呼び出しを非常に簡単に検出できList<>.append(x)ます。ここで、xは1つのオブジェクトのみを参照できます。

于 2009-09-24T11:29:05.450 に答える