"Using an unassigned local variable" in an if statement using TryParse using dynamic

I just entered the following code in the VS2015.Net v4.5.2 console application:

dynamic fromString = "blah", toString = "blah2"; DateTime fromDate, toDate; if (DateTime.TryParse(fromString.ToString(), out fromDate) && DateTime.TryParse(toString.ToString(), out toDate)) { Console.WriteLine(fromDate); Console.WriteLine(toDate); } 

Somewhat unexpectedly, I get the error message "Using an unassigned local variable toDate". I did not expect this, because the if statement is only entered if "toDate" gets the value from the second TryParse.

Needless to say, you can get around it by setting the "toDate" value:

 DateTime fromDate, toDate = DateTime.MinValue; 

or changes to && so that both TryParses are executed regardless of the first failure.

However, I wonder why the error occurs? If the fromString and toString variables were strings, an error does not occur, and the compiler does not report an error that toDate is not assigned. So I wonder why the compiler treats string and dynamic.ToString() differently?

+4
source share
2 answers

This was a dramatic change to Roslyn, documented here :

Certain assignment rules implemented by previous compilers for dynamic expressions allow some cases of code that can lead to reading variables that are not specifically assigned. See https://github.com/dotnet/roslyn/issues/4509 for a single report on this.

[illustrative example]

Because of this feature, the compiler does not have to compile this program if val has no initial value. Previous versions of the compiler (before VS2015) allowed this program to compile, even if val has no initial value. Roslin is now diagnosing this attempt to read a possibly uninitialized variable.

+1
source

This is because you use the & & short circuit operator, which means that if the first TryParse returns false, the second TryParse never executes, so the ToDate variable is not assigned.

Try replacing && by and your error will disappear, because TryParse calls will now always be executed.

The compiler is simply not smart enough (it does not analyze your logic) to know that the code inside will not be executed in some cases.

EDIT: @Simon, I re-read your question and found that you already knew about it ... Maybe because .ToString always exists on the object, but not always on the dynamic (for example, when it is a com object), and in this case the compiler does fewer checks?

+3
source

Source: https://habr.com/ru/post/1014223/


All Articles