1

次のコードを参照してください。

    List<Vector2> axes = new List<Vector2>();
    axes.Add(TopRight() - TopLeft());
    axes.Add(BottomLeft() - TopLeft());
    axes.Add(otherRectangle.TopRight() - otherRectangle.TopLeft());
    axes.Add(otherRectangle.BottomLeft() - otherRectangle.TopLeft());
    // Try normalizing vectors?
    foreach (Vector2 axis in axes)
    {
        axis.Normalize();
    }

メソッドは、Vector2.Normalize()呼び出されたベクトルを正規化する void メソッドです。しかし、何らかの理由でこのループを実行すると、ベクトルが正規化されません。この方法でリストを変更できないのでしょうか?

いくつかの奇妙な点:

  • for ループで繰り返します。つまり、axis[i].Normalize()機能しません。
  • 組み込みList<T>.ForEachイテレータを使用した反復は機能しません。
  • リストを反復処理するのではなく、リストに追加する前にベクトルを正規化して作成すると機能ます。

繰り返しがうまくいかないのはなぜですか?

4

3 に答える 3

4

foreachループは、シーケンス要素のローカル コピーを作成します。コピーを正規化するだけです。

次のようなことをする必要があります。

for(int i=0; i<axes.Count; i++)
    axes[i] = Vector2.Normalize(axes[i]);

この非直感的な動作は、再び、構造体を変更するインスタンス メソッドがなぜ悪い考えであるかを示しています。

于 2012-11-17T10:16:11.283 に答える
3

CodesInChaosVector2.Normalizeが言ったように、これは不適切に設計された方法です (この決定の理由はおそらくパフォーマンスの考慮事項ではありませんが、ここでは役に立ちません)。

結果として、それが作用するオブジェクトを変異させます。ただし、そのオブジェクトは一見すると元のオブジェクトのコピーforeachです。したがって、コードはオブジェクトのみを変更し、実際のリスト内のオブジェクトは変更しません。

for唯一の回避策は、リスト内の項目に対してインデックス付きループを使用することです。

for (int i = 0; i < axes.Count; i++) {
    Vector2 copy = axes[i];
    copy.Normalize();
    axes[i] = copy;
}

ここでは、コピーを変更しますが、後で実際のベクター内にコピーして戻します。単純に書くだけでは変更できないことに注意してください。これは間違いなく (そして私の意見では) .NETのもう 1 つの設計上の欠陥です。その理由は、操作がプロパティ アクセス (プロパティへのアクセス) であり、元のオブジェクトのコピーが返されるためです。axes[i]axes[i].Normalize()axes[i]this[]

于 2012-11-17T10:38:02.613 に答える
0

詳細な編集: 最初にベクトルを正規化してから、それらをリストに追加してみてください...

List<Vector2> axes = new List<Vector2>();

Vector2 tempTopRightTopLeftVector = TopRight() - TopLeft();
tempTopRightTopLeftVector.Normalize();
axes.Add(tempTopRightTopLeftVector);

Vector2 tempBottomLeftTopRightVector = BottomLeft() - TopLeft();
tempBottomLeftTopRightVector.Normalize();
axes.Add(tempBottomLeftTopRightVector);

// and so on for other vectors...

その他の編集:

別のタイプのコレクションを使用してみてください。配列の例:

Vector2[] axes = new Vector2[] {
   TopRight() - TopLeft(),
   BottomLeft() - TopLeft(),
   otherRectangle.TopRight() - otherRectangle.TopLeft(),
   otherRectangle.BottomLeft() - otherRectangle.TopLeft()
}
for(int i=0; i<axes.Length; i++)
{
   axes[i].Normalize();
}
于 2012-11-17T10:20:36.697 に答える