Can I use an out parameter with a recursive method? If it’s possible, how can I do it with the following code?
private void PrepareDir(out List<_File> listFiles,string root,string dirPath) {
DirectoryInfo dirRoot = new DirectoryInfo(dirPath);
FileInfo [] Files = dirRoot.GetFiles();
dirPath = dirPath.Substring(root.Length);
foreach (FileInfo file in Files) {
_File _file = new _File();
_file.Name = dirPath + "\\" + file.Name;
_file.Path = file.FullName;
_file.Size = file.Length;
listFiles.Add(_file);
}
foreach (DirectoryInfo dir in dirRoot.GetDirectories()) {
PrepareDir(out listFiles, root, dir.FullName);
}
}
private void btnButton1_Click(object sender, EventArgs e) {
List<_File> Files = new List<_File>();
PrepareDir(out Files,currAddress, currAddress);
}
I decided to rewrite my answer to be more direct about why using
outis not necessary here. I wrote this to be rather lengthy, because I think the root of your question is more in not understanding the differences between passing by value, passing by reference, and the common confusion between a reference type being passed by reference. Also note that this isn’t explicit to only recursion.In C#, reference types are passed by value by default. A lot of people can confuse a reference type with passing by reference, but there is an important difference. To make myself more clear, I will refer to a reference type as is, and passing by reference as using the
reforoutkeywords.Passing a reference type by value, because it is a reference to some storage location in memory, allows you to make and persist changes. Take this example.
What will happen here, is that the class
typewill now have a value of one. This is the nature of a reference type. Iftypewere astruct, it would still have a value of 0 inside the Foo method, because a copy was made instead of holding a reference to the object.Now that I hope you understand the symantics of passing a reference type by value, let’s actually talk about passing a reference type by reference. This is done using the
outandrefkeywords. Make it a point to note immediately that in the CLR,outtechnically does not exist, onlyrefdoes.outis actually represented in metadata asrefwith a special attribute applied to it, and they ought to be treated the same.Now let’s say we wanted to re-assign our reference type in the
AddOnemethod before doing the addition.Because we are still passing our reference type by value, the value of
typein the methodFoowill still be 0. All we did was initialize another storage location in memory, instead of reassigning the original storage location). But we want to actually pass our reference type by reference, so we should really do:Now the value of
typein theFoomethod will be 1. This is because we reused the same storage location that the reference pointed to, instead of creating a new location in memory.So how does all this apply to
out? Remember thatoutis the same asrefwith different usage symantics. The difference is that withrefyou may leave the method without the reference being initialized, whereas without, you must explicitly initialize it before the method returns.So in your case of using
outhere, it is completely not necessary because you already have existing reference symantics working for you. I hope this clears up a bit.