Как мне получить доступ к "этому" из метода расширения C #?

StackOverflow https://stackoverflow.com/questions/304041

  •  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 модификатор аргумента, который, по-видимому, вряд ли сработает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top