[英]C# Class as other class variable, scope of live
我創建了一小段代碼以測試項目的一部分。 它正在工作,但是我有一些疑問...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace testtodel
{
class Program
{
private class BucketItems
{
private List<Item> ItemList;
private Item item;
public BucketItems()
{
//item = new Item();
ItemList = new List<Item>();
}
public void AddBucketItem(int _Start, int _End)
{
item = new Item();
item.SetItem(_Start, _End);
ItemList.Add(item);
}
public void PrintItemList()
{
for (int i = 0; i < ItemList.Count(); i++)
{
Console.WriteLine("Item: " + i.ToString() + " S: " + ItemList[i].Start.ToString() + " E: " + ItemList[i].End.ToString() + " D: " + ItemList[i].Range.ToString());
}
}
}
private class Item
{
public int Range { get; set; }
public int Start { get; set; }
public int End { get; set; }
public void SetItem(int _Start, int _End)
{
Start = _Start;
End = _End;
Range = _End - _Start;
}
}
static void Main(string[] args)
{
BucketItems bucketItems = new BucketItems();
bucketItems.AddBucketItem(0, 100);
bucketItems.AddBucketItem(200, 300);
bucketItems.AddBucketItem(700, 1000);
bucketItems.PrintItemList();
Console.ReadLine();
}
}
}
我不完全了解的東西與線有關
item = new Item();
正如您在代碼中看到的那樣,有兩行是這樣的,其中一行已注釋,而另一行未注釋。
Part_1:按原樣執行代碼時,每次調用“ AddBucketItem”方法時,它將創建一個“ Item”類的新實例,然后“ Item.SetItem”將設置“開始”,“結束”,“范圍” '在'item'變量中,它將被添加到'ItemList'中。
第2部分:當我要評論現有的“ item = new Item();”時 行和取消注釋其他一個,那么我將期待以下內容。 創建BucketItem類的新實例時,它還將創建“ Item”的新實例,這是在“ BucketItem”構造函數中定義的。 然后,當調用“ AddBucketItem”方法時,“ item”變量將由“ item.SetItem”設置,然后添加到ItemList。 第一次迭代就可以。 但是,如果我再次使用新的“開始”和“結束”參數調用“ AddBucketItem”方法,這也會更改已添加的ItemList [0]。
問題:
為什么在Part_2中的每個調用都會更改已經添加到ItemList中的所有元素? 唯一的解釋是列表中的所有元素都存儲着對“ item”變量的引用,並且當通過更改(開始,結束,持續時間)更改此變量時,它還將更改所有ItemList。 但是我不知道這是正確的解釋,還是我不知道為什么會這樣。 但是,我假設答案是不同的,因為即使我做與“ Part2”中完全相同的操作,以下示例也將按預期填充列表。.我有變量,我正在更改變量的值,我要添加此變量列出。
int new_val; List<int> _lst = new List<int>(); for (int i = 0; i < 10; i++) { new_val = i; _lst.Add(new_val); } for (int i = 0; i < _lst.Count(); i++) { Console.WriteLine("ListIdx: " + i.ToString() + " Value: " + _lst[i].ToString()); }
有人可以請問我的問題嗎?
在您的示例中, new_val
是int
,它是value類型 。
同時,在第一個代碼段中, Item
是一個類,它是引用類型 。
如果使用Part_2
描述的Part_2
,則實際上是對一個對象進行操作。 因此,您的ItemList
包含N個項目,它們都是相同的對象。
在Part_1
,每次調用AddBucketItem
,都會創建一個新對象並將其附加到列表中。 在Part_2
,每次調用AddBucketItem
,都將修改單個原始Item
對象。
您可能需要閱讀有關MSDN上的值類型和引用類型的一些信息:
https://msdn.microsoft.com/zh-CN/library/4d43ts61(v=vs.90).aspx
您需要了解,在C#中,對象是通過引用傳遞的,而原始類型是通過值傳遞的。
因此,您對AddBucketItem
示例的理解是正確的。 Item
對象在BucketItems
構造函數中僅創建一次。 調用AddBucketItem()
,您正在修改原始實例並將其引用添加到列表中。 因此,最后,您將獲得一個列表,其中包含所有指向同一對象實例的單個項目。
對於您提供的第二個示例,它的行為有所不同,因為對於int
類型(它是原始數據類型),傳遞給Add()
函數的值是整數的副本,而不是引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.