Inline variable declaration outside of scope

Viewed 120

Let's say I have two dictionaries with the same keys but with different values.

var metrics1 = new Dictionary<string, double>()
{
    { "Albert", 1.5513 },
    { "Becca", 3.3184 },
    { "Colton", -4.4001 },
    { "Danielle", 6.7 }
};
var metrics2 = new Dictionary<string, double>()
{
    { "Albert", 0.84156 },
    { "Becca", -6.7525 },
    { "Colton", 1.1102 },
    { "Danielle", 0.507944 }
};

If I then choose a dictionary at random to get a value from, using the ternary operator ?:, Visual Studio says that I can inline declare a variable.

var rng = new Random();
var name = "Albert"; // Any name that's present in both dictionaries above

/* Unmodified code */
double metric;
var validName = rng.NextDouble() > 0.5
                    ? metrics1.TryGetValue(name, out metric)
                    : metrics2.TryGetValue(name, out metric);

/* After suggestion was applied */
// double metric;
var validName = rng.NextDouble() > 0.5
                    ? metrics1.TryGetValue(name, out double metric) // 'metric' is declared here?
                    : metrics2.TryGetValue(name, out metric);

Why is it that the metric variable in the modified version can be populated by both sides of the ternary ?: operator? Should it not be contained entirely in the scope of the first branch?

1 Answers

Let me answer your comment, // 'metric' is declared here? first. Yes, metric is declared there (well... not technically... see below). To test this try to declare it in the second arm of the ternary statement; if you do this you get,

error CS0841: Cannot use local variable 'metric' before it is declared

on the line containing the first arm. As to,

Why is it that the metric variable in the modified version can be populated by both sides of the ternary ?: operator?

Because the compiler compiles that code to IL that looks something like the IL that would be generated for the previous code, which means in both cases the declaration is above both arms of the ternary assignment.

So for,

Should it not be contained entirely in the scope of the first branch?

the answer is no, because in both cases the declaration is in the scope of the method above the ternary assignment that is also within that scope.

Essentially, the second implementation is just syntactic sugar for the first.

Related