2 回答

TA貢獻(xiàn)2065條經(jīng)驗(yàn) 獲得超14個(gè)贊
據(jù)我了解,發(fā)生這種情況是因?yàn)榫幾g器知道數(shù)組并且不會(huì)為其調(diào)用索引器。根據(jù) MSDN 的說法,對(duì)于列表,它調(diào)用索引器,而對(duì)于索引器,您不能使用 ref(索引器簽名中沒有 ref)。
為了這
?var firstElement = myArray[0];
?firstElement.head = 99;
Ildasm 展示了這一點(diǎn)
ldelem? ? ?valuetype [System.Runtime]System.ValueTuple`2<int32,int32[]>
微軟軟件定義網(wǎng)絡(luò)
即IL 級(jí)別支持?jǐn)?shù)組。
而對(duì)于列表,它調(diào)用索引器。
?callvirt? ?instance !0 class [System.Collections]System.Collections.Generic.List`1<valuetype [System.Runtime]System.ValueTuple`2<int32,int32[]>>::get_Item(int32)
對(duì)于索引器來說,如果您將 ref 放入簽名中,它就可以工作。
例如(僅用于演示目的;是的,應(yīng)該有數(shù)組而不是單個(gè)變量等,但只是為了使其可編譯)
class Program
{
? ? static void Main(string[] args)
? ? {
? ? ? ? var myList = new MyList<(int head, int[] tail)> {
? ? (0, new[] { 1, 2, 3 }),
? ? (7, new[] { 8, 9 }? ?), };
? ? ? ? ref var firstElement = ref myList[0];
? ? ? ? firstElement.head = 99;
? ? ? ? Console.WriteLine("Hello World!");
? ? }
}
public class MyList<T> : IEnumerable
{
? ? private T value;
? ? public ref T this[int index]
? ? {
? ? ? ? get
? ? ? ? {
? ? ? ? ? ? ?return ref value;
? ? ? ? }
? ? }
? ? public void Add(T i)
? ? {
? ? ? ? value = i;
? ? }
? ? public IEnumerator GetEnumerator() => throw new NotImplementedException();
}
PS但是當(dāng)你開始實(shí)現(xiàn)你自己的列表實(shí)現(xiàn)(作為數(shù)組列表)時(shí),你可能會(huì)注意到,不值得擁有引用索引器 - 想象你調(diào)整了數(shù)組的大小 - 創(chuàng)建了新的數(shù)組并復(fù)制了所有數(shù)據(jù);這意味著某人可能持有非實(shí)際參考。
PPS 更進(jìn)一步,假設(shè)我們創(chuàng)建鏈接列表 - 只是調(diào)整大小不會(huì)發(fā)生任何錯(cuò)誤,但想象我們刪除了某人持有引用的元素 - 不可能理解它不再屬于列表。
所以,是的,我認(rèn)為他們故意將列表索引器設(shè)置為非引用,因?yàn)閷?duì)于可以更改的內(nèi)容返回引用似乎不是一個(gè)好主意。

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超6個(gè)贊
您可以使用WeakReference并更改ValueTuple為類來執(zhí)行此操作:
List<MyClass> myList = new List<MyClass> {
? ? new MyClass { Head = 0, Tail = new[] { 1, 2, 3 } },
? ? new MyClass { Head = 7, Tail = new[] { 8, 9 } } };
var firstElement = new WeakReference(myList[0]);
MyClass reference = firstElement.Target as MyClass;
reference.Head = 99;
firstElement.Target = new MyClass { Head = 99, Tail = reference.Tail};
Console.WriteLine(myList[0].Head);
- 2 回答
- 0 關(guān)注
- 159 瀏覽
添加回答
舉報(bào)