2012-10-02 29 views
3

這可能有點不好意思,但我似乎無法找到有關此行爲的任何信息。C#單行列表行爲

下面是代碼:

class Cars 
{ 
    public int year = 0; 
    public string make = " "; 
    public string model = " "; 

    public Cars() 
    { 
    } 

    public Cars(int tYear, string tMake, string tModel) 
    { 
     year = tYear; 
     make = tMake; 
     model = tModel; 
    } 

    public string ConvertToString() 
    { 
     return year.ToString() + make + model; 
    } 
} 

class Program 
{ 
    Cars oneCar = new Cars(); 
    List<Cars> manyCars = new List<Cars>(); 

    public void Init() 
    { 
     manyCars.Add(new Cars(1993, "Nissan", "240SX")); 
     manyCars.Add(new Cars(2001, "Isuzu", "Rodeo")); 
     manyCars.Add(new Cars(2010, "Ford", "F150")); 

     oneCar = manyCars[2]; 
     oneCar.model = "Pinto"; 

     for (int i = 0; i < manyCars.Count(); i++) 
      Console.WriteLine(manyCars[i].ConvertToString()); 

     Console.WriteLine(oneCar.ConvertToString()); 
    } 

    static void Main(string[] args) 
    { 
     Program prg1 = new Program(); 
     prg1.Init(); 
    } 
} 

輸出是這樣的:

1993Nissan240SX

2001IsuzuRodeo

2010FordPinto

2010FordPinto

爲什麼第三行讀取Pinto而不是F150?它似乎將oneCar變量設置爲指針或其他東西。這怎麼可以避免?我認爲這就是「新」關鍵字所完成的。

在此先感謝您的幫助。

+4

請仔細閱讀http://pobox.com/~skeet/csharp/references.html –

+1

您將需要克隆manyCars [2],然後進行更改克隆的對象。 – d89761

回答

5

因爲Cars是一個對象,在C#中的對象是Reference Types

當你調用這行代碼:

oneCar = manyCars[2]; 

您都指向oneCarmanyCars[2]的存儲位置。他們正在引用同一個對象。更新oneCar也更新manyCars[2]

This link在Reference和Value類型上有很好的寫法。

+0

謝謝了,精確地回答了我的問題。不知道引用/值類型的處理方式不同。 –

3

manyCars[2]是福特。所以在分配oneCar之後是同一輛福特。但請記住,類的類型是引用類型。這意味着oneCarmanyCars[2]指向相同的汽車對象!因此設置oneCar.model = "Pinto"的效果與設置manyCars[2].model = "Pinto"的效果相同。

oneCar = manyCars[2];不會創建對象內容的副本。你可以一個Clone方法添加到汽車類

public Cars Clone() 
{ 
    return (Cars)MemberwiseClone(); // This method is inherited from object. 
} 

那麼這真的創建了一個副本

oneCar = manyCars[2].Clone(); 

現在oneCarmanyCars[2]是兩個不同的對象,改變oneCar's模式不會影響manyCars[2]模型。

2

在c#中有值和引用類型 - 一個類是引用類型。上面的代碼將三個新車對象添加到ManyCars列表中 - 然後將OneCar變量設置爲第三個列表元素的引用 - 在您的情況下爲F150。然後用Pinto覆蓋模型屬性,然後遍歷列表。

你已經基本上將OneCar設置爲指向原始Car對象的指針。如果您想製作一個對象的副本,然後在不影響列表中的原始對象的情況下進行更改,則需要克隆Car對象,而不是將其分配給OneCar變量。

乾杯 西蒙