2013-08-23 63 views
4

我正在從Java轉移到C#,並且一直在編寫一些示例程序。現在我遇到了不同對象列表(IUnit),當我調用列表中的某個值來更改其值時,它會更改所有值。我已經添加了對List的引用 - 按照其他Stack溢出問題。參考不改變值的列表

所以,我有以下類

interface IUnit 
{ 
    int HealthPoints { set; get; } 
    String ArmyType { get; } 
} 

這是基類,我稱之爲創建軍團類型(海軍陸戰隊員/步兵)的列表。實現是一樣的,期望對類內的值進行更改。

public class Infantry : IUnit 
{ 
    private int health = 100; 
    protected String armyType = "Infantry"; 
    public int HealthPoints 
    { 
     get 
     { 
      return health; 
     } 
     set 
     { 
      health = value; 
     } 
    } 
    public String ArmyType 
    { 
     get 
     { 
      return armyType; 
     } 
    } 

然後我用下面的代碼

List<IUnit> army = new List<IUnit>(); 
Infantry infantry = new Infantry(); 
Marine marine = new Marine(); 
army.Add(Marine); 

然後,我有一個方法,它只是帶走25從健康點初始化列表。

public void ShotRandomGuy(ref List<IUnit> army) 
    { 
     army[0].HealthPoints = army[0].HealthPoints - 25; 
    } 

然後我按如下所示調用該方法。

battle.ShotRandomGuy(ref army); 

但是,它需要從列表中的所有對象中取消25。我會如何阻止它呢?我已經添加了對列表的引用,所以我認爲它會將它從原始列表中刪除。我需要克隆列表嗎?這會起作用嗎?

還是更多的是設計問題?

謝謝!

+1

寫一些東西來改變屬性的數值你在列表中多次添加了同樣的'marine'實例嗎? –

+5

你誤解了'ref'開頭。你的'ShotRandomGuy'方法根本不需要使用'ref'。請參閱http://yoda.arachsys.com/csharp/parameters.html您還應該瞭解自動實施的屬性。 –

+0

閱讀以下內容,它將有所幫助:http://stackoverflow.com/questions/5501374/basic-difference-between-value-types-and-reference-types –

回答

4

看起來像是多次添加同一個單元實例列表。因此,所有列表項都指向內存中的單個對象。修改任何項目都會修改該對象。

List<IUnit> army = new List<IUnit>(); 
Infantry infantry = new Infantry();  

for(int i = 0; i < 10; i++) 
{ 
    // adds same instance each time   
    army.Add(infantry); 
} 

您應該在向列表添加單位時實例化新單位。例如。

List<IUnit> army = new List<IUnit>(); 

for(int i = 0; i < 10; i++) 
{ 
    // create new instance each time 
    Infantry infantry = new Infantry(); 
    army.Add(infantry); 
} 

BTW你不需要ref這裏:

public void ShotRandomGuy(List<IUnit> army) 
{ 
    Random r = new Random(); 
    var unit = army[r.Next(army.Count)]; 
    unit.HealthPoints -= 25; 
} 
+0

中沒有這種行爲的理由,這是完全有道理的。那麼,我將如何去創建每個單元的不同實例,從而在內存中擁有多個對象呢? –

+1

@JamesReeves我已添加示例以顯示區別 –

+0

呃,對不起 - 我已經這樣做了。但它仍在改變所有的對象值。 我應該給出一個更好的例子。抱歉。 –

0
  1. 你並不需要通過列表作爲參考,如果你不打算軍隊設置爲另一個列表
  2. 你忘記添加步兵清單​​? List army = new List(); 步兵=新步兵(); Marine marine = new Marine(); army.Add(Marine);
+0

不是這是一個例子。我應該包括軍隊。步兵(步兵)。對不起 –

+0

你能提供你的應用程序的完整代碼嗎?在示例代碼 – Nikolay

0

你可以保持infantrymarine在列表中,並通過排序他們for

像這樣的東西可以用於實例化列表。

breadCollection = new List<InteractiveObject>(); 


for(int i = 0; i < totaltObjects; i++) 
    breadCollection.ElementAt(i).Add(new InteractiveObject()); 

無論何時您必須訪問list的內容才能進行更改,請執行如下操作。

int shotUnit?;  

shotUnit = unitNumber 
if(shot != null) 
{ 
    breadCollection.ElementAt(i).Remove(alive) 
    breadCollection.ElementAt(i).Add(dead) 
    shotUnit = null; 
} 

我相信這會適用於您的問題。你也可以用