public ref string FindAuthor(int number, string[] names)
{
if (names.Length > 0)
return ref names[number];
throw new IndexOutOfRangeException($"{nameof(number)} not found.");
}
//main method
string[] authors = { "Mahesh Chand", "Mike Gold", "Dave McCarter",
"Allen O'neill", "Raj Kumar" };
//first variation
string author4 = new Program().FindAuthor(3, authors);
Console.WriteLine("Original author:{0}", author4);
author4 = "Chris Sells";
Console.WriteLine("Replaced author:{0}", authors[3]);
//secondvariation
ref string author4 = ref new Program().FindAuthor(3, authors);
Console.WriteLine("Original author:{0}", author4);
author4 = "Chris Sells";
Console.WriteLine("Replaced author:{0}", authors[3]);
So the FindAuthor
returns by reference and when I capture that in ref string author4
and then modify it, the authors
array changes as expected.
But when I say string author4
and then modify the author4
then the authors
does not change but it kind of does not make sense to me since the FindAiythor
method always returns by reference so shouldn't author4
always change the reference?
Could you please tell me what happens here (under the hood maybe)?
When you say string author4 = {expr}
instead of ref string author4 = ref {expr}
, the method returns a reference to the string-reference, and the compiler immediately de-references that, storing just the string-reference (not the reference to the string-reference) in the local. At that point: all changes to author4
are just changing the local variable, hence no update to authors
. With the full ref
version, the assignment to author4
is an indirect write; the value of the local is never changed; instead the value is used to determine where to do the actual write.
In reality, this seems like an unusual choice for a ref
return.