2017-08-14 57 views
0

随着代码:结构扩展方法

someVector.FixRounding(); //round vector's values to integers if the difference is 1 epsilon 
float x = someVector.x; //still getting old value 

public static void FixRounding(this Vector3 v) 
{ 
    if (Mathf.Approximately(v.x, Mathf.Round(v.x))) v.x = Mathf.Round(v.x); 
    if (Mathf.Approximately(v.y, Mathf.Round(v.y))) v.y = Mathf.Round(v.y); 
    if (Mathf.Approximately(v.z, Mathf.Round(v.z))) v.z = Mathf.Round(v.z); 
} 

的FixRounding方法实际上并没有改变载体的价值观虽然Mathf.Approximately返回true。

+0

请注意,截图会显示一个可能已经四舍五入的值。这就是为什么我建议使用往返格式或使用“BitConverter.DoubleToInt64Bits”显式转换为字符串。 –

+0

@AlexeiLevenkov:现在完成 - 您可能想要删除您的评论。 –

回答

5

此声明:

public static void FixRounding(this Vector3 v) 

...含义v是由价值通过,这是一个结构,假设documentation是正确的。因此,您对它所做的任何更改都不会被调用者看到。你需要使它成为一个常规的方法,并通过引用传递v

public static void FixRounding(ref Vector3 v) 

,并称呼其为:

TypeDeclaringMethod.FixRounding(ref pos); 

这里的扩展方法的示威,试图修改通过值未能通过结构:

using System; 

struct Vector3 
{ 
    public float x, y, z; 

    public override string ToString() => $"x={x}; y={y}; z={z}"; 
} 

static class Extensions 
{ 
    public static void DoubleComponents(this Vector3 v) 
    { 
     v.x *= 2; 
     v.y *= 2; 
     v.z *= 2; 
    } 

    public static void DoubleComponentsByRef(ref Vector3 v) 
    { 
     v.x *= 2; 
     v.y *= 2; 
     v.z *= 2; 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     Vector3 vec = new Vector3 { x = 10, y = 20, z = 30 }; 
     Console.WriteLine(vec); // x=10; y=20; z=30 
     vec.DoubleComponents(); 
     Console.WriteLine(vec); // Still x=10; y=20; z=30 
     Extensions.DoubleComponentsByRef(ref vec); 
     Console.WriteLine(vec); // x=20; y=40; z=60 
    } 
} 

现在,如果Vector3是类,印刷将是X = 20的第二行; Y = 40; z = 60 ...但是因为它是一个结构体,所以修改传递的值并不会从调用者的角度改变它。通过引用来修复它,因此是第三行输出。

+0

带结构的扩展方法似乎是这里的问题。如果我没有遗漏什么,问题就解决了。 – MCpiroman

+0

@MCpiroman:现在我将删除我的所有评论(包括问题和答案)。我已经重新打开了这个问题,因为它现在显然不是浮点问题 –

+0

但仍然重复:https://stackoverflow.com/a/11725046/7249108 – MCpiroman