亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我可以通過引用返回來獲取列表項嗎?

我可以通過引用返回來獲取列表項嗎?

C#
繁華開滿天機 2023-07-09 16:13:19
我有一個要修改的元組列表。    var myList = new List<(int head, int[] tail)> {        (0, new[] { 1, 2, 3 }),        (7, new[] { 8, 9 }   ), };    var myArray = new (int head, int[] tail)[] {        (0, new[] { 1, 2, 3 }),        (7, new[] { 8, 9 }   ), };    // ...    // ref var firstElement = ref myList[0];    ref var firstElement = ref myArray[0];    firstElement.head = 99;這非常適合數組,但不適用于列表。我知道這是因為索引器不執行引用返回;但是列表是否可以通過其他方式通過引用返回其元素,以便我可以修改返回的元組?這將導致編譯器錯誤“屬性或索引器可能無法作為 out 或 ref 參數傳遞”:ref var firstElementList = ref myList[0];
查看完整描述

2 回答

?
翻翻過去那場雪

TA貢獻2065條經驗 獲得超14個贊

據我了解,發生這種情況是因為編譯器知道數組并且不會為其調用索引器。根據 MSDN 的說法,對于列表,它調用索引器,而對于索引器,您不能使用 ref(索引器簽名中沒有 ref)。


為了這


?var firstElement = myArray[0];


?firstElement.head = 99;

Ildasm 展示了這一點


ldelem? ? ?valuetype [System.Runtime]System.ValueTuple`2<int32,int32[]>

微軟軟件定義網絡

即IL 級別支持數組。


而對于列表,它調用索引器。


?callvirt? ?instance !0 class [System.Collections]System.Collections.Generic.List`1<valuetype [System.Runtime]System.ValueTuple`2<int32,int32[]>>::get_Item(int32)

對于索引器來說,如果您將 ref 放入簽名中,它就可以工作。


例如(僅用于演示目的;是的,應該有數組而不是單個變量等,但只是為了使其可編譯)


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但是當你開始實現你自己的列表實現(作為數組列表)時,你可能會注意到,不值得擁有引用索引器 - 想象你調整了數組的大小 - 創建了新的數組并復制了所有數據;這意味著某人可能持有非實際參考。


PPS 更進一步,假設我們創建鏈接列表 - 只是調整大小不會發生任何錯誤,但想象我們刪除了某人持有引用的元素 - 不可能理解它不再屬于列表。


所以,是的,我認為他們故意將列表索引器設置為非引用,因為對于可以更改的內容返回引用似乎不是一個好主意。


查看完整回答
反對 回復 2023-07-09
?
慕妹3242003

TA貢獻1824條經驗 獲得超6個贊

您可以使用WeakReference并更改ValueTuple為類來執行此操作:


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);

查看完整回答
反對 回復 2023-07-09
  • 2 回答
  • 0 關注
  • 175 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號