Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
284 views
in Technique[技术] by (71.8m points)

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...