2013-03-22 36 views
2

我正在爲C#中的遊戲構建內部邏輯,並且來自C++,這對於我來說可能會在翻譯時丟失。通過引用或變通方法存儲對象

我有一個對象,能夠計算它提供的獎金並將其作爲整數值返回。計算意圖是動態的,並且可以根據各種變量而改變。

public class Ability: Buffable 
    { 

     public string abbr { get; private set; } 

     public Ability(string name, string abbr, uint score) : base(name, score) 
     { 
      this.abbr = abbr; 
     } 

     // Ability Modifier 
     // returns the ability modifier for the class. 
     public int Ability_modifier() 
     { 
      const double ARBITARY_MINUS_TEN = -10; 
      const double HALVE = 2; 
      double value = (double)this.Evaluate(); 
      double result = (value + ARBITARY_MINUS_TEN)/HALVE; 

      // Round down in case of odd negative modifier 
      if (result < 0 && ((value % 2) != 0)) 
      { 
       result--; 
      } 
      return (int)result; 
     } 

然後我有另一個對象,技能,應該知道該獎金並將其添加到它的計算。我想通過引用將技能傳遞給Skill的構造函數,然後存儲該引用,以便在能力改變計算的情況下也可以。這顯然存儲引用的明顯問題是C#中的禁忌。

是否有解決這個問題的方法或解決這個問題的方法,我的指針感染的思維不被考慮?我非常希望不必每次都將能力傳遞給評估Skill的函數,因爲引用的那個函數在構建之後永遠不會改變。

回答

3

這是一個明顯的問題,顯然存儲引用是C#禁忌。

絕對不是。引用存儲在整個地方。你在這裏做,例如:

this.abbr = abbr; 

System.String是一類,因此,引用類型。所以價值abbr是一個參考。

我強烈懷疑你誤解了引用類型在C#中的工作方式。如果您記得一個參考對象,那麼對該對象的更改將通過該參考可見。但是,您複製的原始表達式的更改將不會生效。

例如,使用StringBuilder作爲一個方便的可變的引用類型:

StringBuilder x = new StringBuilder("abc"); 

// Copy the reference... 
StringBuilder y = x; 

// This changes data within the object that x's value refers to 
x.Append("def"); 

// This changes the value of x to refer to a different StringBuilder 
x = new StringBuilder("ghi"); 

Console.WriteLine(y); // abcdef 

參見references and values,並parameter passing in C#我的文章更多的細節。

+0

謝謝,我絕對誤解了這是如何工作的。這些文章相當有幫助。 – stygma 2013-03-23 18:04:14

-1

在C#中,有引用類型和值類型。所有非值類型的對象都通過引用傳遞,所以引用不應該存在問題。只要通過它,它將通過引用傳遞。

+4

不,對象不通過引用傳遞 - 引用通過值傳遞(默認情況下)。對於'ref'參數,有*真實*通過引用傳遞,它可以應用於參考類型或值類型的參數。 – 2013-03-22 22:46:10

+0

這取決於你對術語「通過引用」的定義,這是有爭議的。我經常見到的一個有用的定義是:「如果一個函數修改一個值,那麼當通過引用傳遞時,這些修改也出現在調用函數的範圍內,而這些調用函數在傳遞值時不會這樣做。」通過這個定義,任何C#「引用類型」將被「通過引用傳遞」,而不是「按值」。在C++中傳遞「按值引用」將使用指向C++開發人員的指針,等於「按引用傳遞」。 – 2013-03-25 19:49:33

+0

不,它是以改變參數值的方式。對參數本身的改變(例如'builder = new StringBuilder()')對調用者不可見。參數值引用的對象內數據的變化(例如'builder.Append(「Foo」)')將會被看到,但是它不會*改變參數本身的值。參數的值只是一個參考,並且參考值將在之後相同。我真的不認爲這裏有任何爭論 - 語言規範非常清晰。 – 2013-03-25 19:55:32

0

我不太滿意你的代碼來給出一個具體的例子,但要做到這一點的方法是傳遞一個lambda委託,如() => object.property而不是:object.property

+0

我認爲你正在回答比OP所提出的更高級的問題。 Eric提供了您的建議的通用實現[此處](http://stackoverflow.com/a/4543089/18192)。 – Brian 2013-03-23 02:33:33

+0

@Brian:我知道這個帖子很好;在過去的幾個月裏,我偶然發現了幾次。但是,我對這篇文章的看法是,OP想要通過重新計算財產的方式,而不是財產的當前價值;我的提議是做到這一點的一種手段。 – 2013-03-23 03:00:19

相關問題