为什么不通过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返回更少。