I'm trying to use declaration patterns as described here: https://learn.microsoft.com/dotnet/csharp/language-reference/operators/patterns#declaration-and-type-patterns
I can see that the examples only mention using declaration patterns in if conditions, like this:
object greeting = "Hello, World!";
if (greeting is string message)
{
Console.WriteLine(message.ToLower()); // output: hello, world!
}
Patterns do generally work outside of if conditions, i.e. anywhere you could put a Boolean expression. So I could write this:
var isString = greeting is string;
But then if I try making it a declaration pattern, I get a compiler error... not from the declaration pattern itself, but only when I try using the declared variable:
var isString = greeting is string str;
Console.WriteLine(str); // Compiler Error CS0165: Use of unassigned local variable 'str'
Intuitively, I would expect the variable str
to be initialized with the value of greeting
just like when I do that in an if condition. Is there a way I can get it to work?
Compare to the following (roughly equivalent) code:
object? greeting = "test";
string str;
bool isString = greeting is string;
if (isString)
{
str = (string)greeting;
}
if (isString)
{
Console.WriteLine(str);
// error CS0165: Use of unassigned local variable 'str'
}
You can see that the variable str
is declared in all cases, but it's only assigned a value if isString
is true
.
The definite assignment analysis isn't able to deduce that if isString
was true
for the Console.WriteLine
test, it must also have been true
for the case which assigns str
, and that therefore str
must be assigned.
Now, with the above code, you can write:
bool isString = greeting is string;
if (isString)
{
str = (string)greeting;
}
else
{
str = "default";
}
// str can now be used, as it is definitely assigned
You can do the same with patterns:
if (greeting is string str)
{
// ...
}
else
{
str = "default";
}