Как получить доступ к «этому» из метода расширения C #? - PullRequest
1 голос
/ 20 ноября 2008

Я работал с 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 .Normalize ().

Кроме того, как сделать это недействительным, как мне отрегулировать это так, чтобы 'v2' был изменен? (По сути, мне нужен доступ к объекту 'this', или мне нужно, чтобы 'v2' передавался по ссылке.)

Edit:

И да, я пробовал это:

    public static void NormalizeOrZero(this Vector2 v2)
    {
        if (v2 != Vector2.Zero)
            v2.Normalize();
    }

Не работает, v2 - это просто переменная в области действия NormalizeOrZero.

Ответы [ 4 ]

3 голосов
/ 20 ноября 2008

Это не работает, потому что Vector 2 на самом деле является структурой . Это означает, что он передается по значению, и вы не можете изменить копию вызывающей стороны. Я думаю, что лучшее, что вы можете сделать, это обходной путь, определенный lomaxxx.

Это показывает, почему вы должны вообще избегать использования структур. См. этот вопрос для получения дополнительной информации. Vector2 нарушает директиву, согласно которой структуры должны быть неизменными, но, вероятно, имеет смысл делать это в контексте XNA.

1 голос
/ 20 ноября 2008

Ну, если вы действительно умираете , чтобы сделать это, вы можете сделать что-то вроде этого:

public static void NormalizeOrZero(this Vector2 ignore, ref Vector2 v2)
{
    if (v2 != Vector2.Zero)
        v2.Normalize();
}

Вы бы назвали это так:

v2.NormalizeOrZero(ref v2);

Это очень уродливо, но это сработает, чего бы это ни стоило. Но в этот момент вы также можете сначала вызвать статический метод.

0 голосов
/ 20 ноября 2008

Вам потребуется модификатор ref и this для аргумента, что вряд ли сработает.

0 голосов
/ 20 ноября 2008

Я не уверен, почему ваш второй пример кода не работает, но если первая партия кода делает то, что вы хотите, вы можете просто обойти это, перейдя:

Vector2 v2 = new Vector2()
v2 = v2.NormalizeOrZero();
...