为什么不通过ref返回集合元素?
以下通过引用返回的示例来自C#7.0中的新function :
public ref int Find(int number, int[] numbers) { for (int i = 0; i < numbers.Length; i++) { if (numbers[i] == number) { return ref numbers[i]; // return the storage location, not the value } } throw new IndexOutOfRangeException($"{nameof(number)} not found"); }
编译时没有任何问题(正如您所期望的那样,它是从Microsoft博客中复制的)。
我写过这个:
private static ref int GetReference(string searchTerm) { var passwords = new Dictionary { {"password", 1}, {"123456", 2}, {"12345678", 3}, {"1234", 4}, {"qwerty", 5}, {"12345", 6}, {"dragon", 7} }; return ref passwords[searchTerm]; }
这个不编译; 它给出以下错误:
CS8156表达式不能在此上下文中使用,因为它可能不会通过引用返回
为什么从数组返回工作,但从集合返回不?
答案就在您发布的相同链接中:
您只能返回“安全返回”的引用:传递给您的引用,以及指向对象中的字段的引用。
你的例子既不满足。 您正在函数内创建列表(因此对象将超出范围并且其指针将无效),并且它不指向对象的字段。
在C#中, ref
适用于:
- 变量(本地或参数)
- 字段
- 数组位置
ref
不适用于:
- 属性
- 活动
- 在C#7的情况下,局部变量由ref返回
请注意,对于字段和数组位置,访问arrays的方式无关紧要。 也就是说, return ref numbers[i];
不会保留numbers
,而是指向它所指向的数组。 与return ref numbers;
不同return ref numbers;
,只有当numbers
是一个字段时才能工作。
但是,你在Dictionary<,>
的索引属性上使用ref
,它根本不是ref
开头所支持的表达式(即即使在C#7之前你也不能将ref passwords[searchTerm]
作为参数传递),通过ref返回更少。