[英]How can I update a reference returned from TryGetValue after its been inserted into a collection?
我在字典里有一本字典。 在將內部字典添加到外部字典后,我想將對內部字典的引用設置為一個值:
var mammalIdSubscribers = new Dictionary<int, Dictionary<Guid, int>>();
var mammalId = 0;
if (!mammalIdSubscribers.TryGetValue(mammalId, out var mammalSubscribers))
mammalIdSubscribers[mammalId] = mammalSubscribers; // Add reference to inner dict to outer dict
Subscribe(ref mammalSubscribers);
/*
mammalIdSubscribers[mammalId] is still null after the call
to Subscribe despite mammalSubscribers being non-null. Why?
*/
static void Subscribe(ref Dictionary<Guid, int> subscribers)
{
subscribers = new Dictionary<Guid, int> { { Guid.NewGuid(), 10 } };
}
不幸的是,這不起作用,我不確定為什么( Console.WriteLine(mammalSubscribers.First().Value);
拋出 null 引用異常)。
有人可以解釋為什么這不起作用嗎? 換句話說,為什么在使用ref
關鍵字調用Subscribe
之后, mammalIdSubscribers[0]
仍然是null
?
您的變量mammalIdSubscribers
和mammalSubscribers
的名稱非常相似,因此為了清楚起見,我將mammalIdSubscribers
重命名為“ outerDict
”或“ biggerDict
”,而mammalSubscribers
重命名為“ encarta
”,因為我經常將其用作參考作為一個 sprog。
逐行...
var biggerDict = new Dictionary<int, Dictionary<Guid, int>>();
biggerDict
字典。var mammalId = 0;
biggerDict.TryGetValue(mammalId, out var encarta)
false
。 out
參數也是一個內聯out
聲明,當您將內聯out
聲明與Dictionary
的TryGetValue
一起使用時,新變量在返回false
時將為null
(或default
)。false
,因為biggerDict
是空的,如前所述。encarta
是null
。encarta
是堆棧上一個新的 GC 引用類型變量,它不是biggerDict
任何部分的別名或“引用” )。TryGetValue
調用在if(.TryGetValue(...) )
語句中,這意味着biggerDict[mammalId] = encarta;
將被評估。
encarta
仍然是null
。biggerDict[mammalId]
(又名biggerDict[0]
)是null
。Subscribe(ref encarta);
encarta
的引用傳遞給Subscribe
。encarta
不是對biggerDict
中任何槽或空間的引用:它仍然只是一個堆棧分配(也稱為自動)對象引用大小的槽,它仍然是null
。encarta = new Dictionary<Guid, int> { { Guid.NewGuid(), 10 } };
Subscribe
內部,在機器語言級別,指向堆棧分配的本地encarta
的指針(-ish)被引用並分配給new Dictionary<Guid, int> { { Guid.NewGuid(), 10 } };
.encarta
現在不是null
。encarta
local 現在是對 GC 堆上有效字典 object 的引用。 但是沒有任何東西調用biggerDict[int].set_Item
屬性設置器來使biggerDict[0]
成為非null
引用encarta
指向的同一個 object 。T[]
),所有其他帶有索引器的類型都只是屬性 getter/setter 方法的糖分, 這意味着 object 引用是按值傳遞的,而不是按引用傳遞的引用——至少不是沒有一個ref
返回屬性, Dictionary<K,V>
沒有。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.