C#拡張メソッド内から「this」にアクセスするにはどうすればよいですか?
-
08-07-2019 - |
質問
Vector2とXNAを使用してきましたが、Zero VectorでNormalize()メンバー関数を呼び出すと、{NaN、NaN}のベクトルに正規化されることがわかりました。これはすべてうまくいきますが、私の場合は、代わりに単にゼロベクトルのままにしておきます。
このコードをプロジェクトに追加すると、かわいい拡張メソッドが有効になりました:
using ExtensionMethods;
namespace ExtensionMethods
{
public static class MyExtensions
{
public static Vector2 NormalizeOrZero(this Vector2 v2)
{
if (v2 != Vector2.Zero)
v2.Normalize();
return v2;
}
}
}
残念ながら、このメソッドは、この拡張メソッドを呼び出すために使用するベクトルを単純に正規化するのではなく、正規化されたベクトルを返します。代わりに vector2Instance .Normalize()と同じように動作させたいと思います。
これを無効にする以外に、「v2」が変更されるように調整するにはどうすればよいですか? (本質的に、「this」オブジェクトにアクセスする必要があるか、参照によって「v2」を渡す必要があります。)
編集:
そして、はい、私はこれを試しました:
public static void NormalizeOrZero(this Vector2 v2)
{
if (v2 != Vector2.Zero)
v2.Normalize();
}
機能しません。v2はNormalizeOrZeroのスコープ内の変数です。
解決
ベクター2 であるため、これは機能しません。実際には構造体。つまり、値で渡され、呼び出し元のコピーを変更することはできません。できる最善の方法は、lomaxxxで指定された回避策だと思います。
これは、一般に構造の使用を避けるべき理由を示しています。詳細については、この質問をご覧ください。 Vector2は、構造体が不変であるべきであるというガイドラインに違反していますが、XNAのコンテキストでそうすることはおそらく理にかなっています。
他のヒント
まあ、本当にあなたがこれを死ぬだけなら、次のようなことができます:
public static void NormalizeOrZero(this Vector2 ignore, ref Vector2 v2)
{
if (v2 != Vector2.Zero)
v2.Normalize();
}
次のように呼び出します:
v2.NormalizeOrZero(ref v2);
それは非常にいですが、それは価値がありますが、動作します。ただし、その時点で、最初から静的メソッドを呼び出すこともできます。
2番目のコードサンプルが機能しない理由はわかりませんが、最初の多くのコードが目的の動作をする場合は、次のようにして回避できます。
Vector2 v2 = new Vector2()
v2 = v2.NormalizeOrZero();
引数には ref
と this
の両方の修飾子が必要になりますが、動作しない可能性があります。