Why doesn't returning by ref work for elements of collections?

一世执手 提交于 2019-12-19 05:13:08

问题


The following example of returning by reference is from What’s New in C# 7.0:

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

That compiles without any problems (as you'd expect as it's copied from the Microsoft blog).

I've written this one:

private static ref int GetReference(string searchTerm)
{
    var passwords = new Dictionary<string, int>
    {
        {"password", 1},
        {"123456", 2},
        {"12345678", 3},
        {"1234", 4},
        {"qwerty", 5},
        {"12345", 6},
        {"dragon", 7}
    };

    return ref passwords[searchTerm];
}

This one doesn't compile though; it gives the following error:

CS8156 An expression cannot be used in this context because it may not be returned by reference

Why does returning from an array work, but returning from a collection doesn't?


回答1:


The answer is in that same link you posted:

You can only return refs that are “safe to return”: Ones that were passed to you, and ones that point into fields in objects.

Your example satisfies neither. You are creating the list inside the function (so the object will go out of scope and its pointer will be invalid), and it doesn't point to a field of an object.




回答2:


In C#, ref works for:

  • Variables (local or parameters)
  • Fields
  • Array locations

ref doesn't work for:

  • Properties
  • Events
  • Local variables in the case of C# 7 return by ref

Note that for fields and array locations, it doesn't matter how you're accessing the array. That is, return ref numbers[i]; doesn't hold on to numbers, but to the array it points to. Quite unlike return ref numbers;, which could only work if numbers was a field.

However, you're using ref on a Dictionary<,>'s index property, it's simply not a supported expression for ref to begin with (i.e. you can't pass ref passwords[searchTerm] as an argument even before C# 7), much less to return by ref.



来源:https://stackoverflow.com/questions/43576471/why-doesnt-returning-by-ref-work-for-elements-of-collections

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!