Как мне получить доступ к "этому" из метода расширения C #?
-
08-07-2019 - |
Вопрос
Я работал с Vector2 и XNA, и я пришел к выводу, что вызов функции-члена 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 ( вектор2института ).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);
Это ужасно некрасиво, но это сработает, чего бы это ни стоило.Но в этот момент вы с таким же успехом можете вызвать статический метод в первую очередь.
Я не уверен, почему ваш второй пример кода не работает, но если первая часть кода делает то, что вы хотите, вы могли бы просто обойти это, перейдя:
Vector2 v2 = new Vector2()
v2 = v2.NormalizeOrZero();
Вам понадобились бы оба ref
и тот this
модификатор аргумента, который, по-видимому, вряд ли сработает.