2017-08-14 101 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