The following works as expected:
dynamic foo = GetFoo();
if (foo != null)
{
if (foo is Foo i)
{
Console.WriteLine(i.Bar);
}
}
It would appear that this is not, in fact, a compiler error.
It was previously reported as a bug here.
However, it has been closed as not a bug. The reason is because of this part of the C# language spec (note: I am quoting here from user gafter on GitHub - this is NOT original content from myself):
If an operand of a conditional logical operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.
Specifically, the && operation is not a compile-time boolean short-circuiting operation because its right-hand operand is of type dynamic.
Subtle stuff, and as DavidG says above, another reason to avoid dynamic where possible! (And I must confess, I'm still not completely convinced it's not a bug, but that's just me not understanding everything I guess...)