2008-11-20 26 views
1

我一直在使用Vector2和XNA,并且我发现调用零向量上的Normalize()成员函数会将其归为{NaN,NaN}向量。这一切都很好,但在我的情况下,我宁愿它,而只是把它们作为零向量。如何从C#扩展方法中访问'this'?

将此代码添加到我的项目启用了一个可爱的扩展方法:

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'被修改? (从本质上讲,我需要访问“这个”对象,或者我需要“V2”通过引用传递。)

编辑:

是的,我已经试过这样:

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

不起作用,v2只是NormalizeOrZero范围内的一个变量。

回答

3

这不起作用因为Vector 2 is actually a struct。这意味着它通过值传递,你不能修改调用者的副本。我认为你可以做的最好的是由lomaxxx指定的解决方法。

这说明了为什么你应该避免使用结构。有关更多信息,请参阅this question。 Vector2违反了结构应该是不可变的指导原则,但在XNA的背景下这样做可能是有意义的。

0

我不知道为什么你的第二个代码示例不工作,但如果第一个大量的代码做你愿意,你可以简单地解决它通过什么去:

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

第二个代码示例是对结构体的一个副本进行变异,所以当它在某种意义上工作时,它不会执行OP希望它做的事情,并且改变对象调用者的操作。 – Servy 2013-04-03 14:55:41

0

您将需要参数上的refthis修饰符,这似乎不大可能奏效。

1

好吧,如果你真的只是死亡要做到这一点,你可以做这样的事情:

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

你会说它是这样:

v2.NormalizeOrZero(ref v2); 

这是强大的丑陋,但它会工作,因为它是值得的。但是在那个时候,你最好先调用静态方法。