2 回答

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

TA貢獻1824條經(jīng)驗 獲得超6個贊
您可以使用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)注
- 147 瀏覽
添加回答
舉報