out parameter assigned by passing it to another function as an out parameter

64 views Asked by At

I wrote a Tree structure and then made a static function to try to parse a Tree from a source file.

public static bool TryParseTreeFromFile(String filePath, out Tree tree) {
    String fileContent;
    using (StreamReader reader = new StreamReader(filePath, true)) {
        fileContent = reader.ReadToEnd();
    }

    List<NodeDescription> nodesDescription;
    List<TreeLevelDescription> levelsDescription;
    bool parsingIsTotal = ExtractInformationFromFile(fileContent, out nodesDescription, out levelsDescription);

    parsingIsTotal = parsingIsTotal && CreateTree(nodesDescription, levelsDescription, out tree);

    return parsingIsTotal;
}

TryParseTreeFromFile, ExtractInformationFromFile and CreateTree are all functions that return a boolean and take out parameters (so that we can parse everything that can be parsed from the file but also notify if all information in the source file could be parsed).

Anyway this function gives me a compilation error: "The out parameter 'tree' must be assigned to before control leaves the current method". Event so the CreateTree will assign it.

I could of course add Tree t;, pass it to the CreateTree function and then assign it to tree but I would like to understand why is this happening, why did designers had to forbid this.

Edit: Modifying the function to declare a Tree, pass it to CreateTree and then assign tree to this variable don't work neither: Use of unassigned local variable 't'

Tree t;
parsingIsTotal = parsingIsTotal && CreateTree(nodesDescription, levelsDescription, out t);
tree = t;   
1

There are 1 answers

0
Jon Skeet On BEST ANSWER

The problem is that you're only conditionally calling CreateTree. Suppose parsingIsTotal is false - then this expression:

parsingIsTotal && CreateTree(...)

will evaluate the left hand operand, find that it's false, and not evaluate the right hand operand.

You get the same sort of error with your proposed fix, for precisely the same reason - you're using t, but t isn't definitely assigned, because CreateTree may not have been called.

If you always want to call CreateTree regardless of the previous value of parsingIsTotal, the simplest solution is just:

parsingTotal &= CreateTree(nodesDescription, levelsDescription, out tree);