Short-Circuit Boolean Logic in C#

VB6 does not have short-circuit evaluation for Boolean operators. This means that all conditions of an And or Or operator will be evaluated.

In this example, both message boxes from the GetTrue and GetFalse methods will be shown.

Private Sub ShortCircuitTest()

    If GetFalse And GetTrue Then
        ...
    Else
        ...
    End If
    
    If GetTrue Or GetFalse Then
        ...
    Else
        ...
    End If
End Sub

Private Function GetTrue() As Boolean
    MsgBox "TRUE"
    GetTrue = True
End Function

Private Function GetFalse() As Boolean
    MsgBox "FALSE"
    GetFalse = False
End Function

VB.NET's Boolean logic works in the same way as it does in VB6, which means that the message boxes will be shown when migrating this code to VB.NET. However, C#'s boolean logic uses short-circuiting, which means that migrating this code will not work the same way as it does in VB6.

private void Form_Load()
{
	if (GetFalse() && GetTrue())
	{
		...
	}
	else
	{
		...
	}

	if (GetTrue() || GetFalse())
	{
		...
	}
	else
	{
		...
	}
}

private bool GetTrue()
{
	MessageBox.Show("TRUE", ...);
	return true;
}

private bool GetFalse()
{
	MessageBox.Show("FALSE", ...);
	return false;
}

Since C# short-circuits && statements, when the first method evaluates to false, it will not continue on evaluating the second metod, so only the first message box will be shown. The same will happen when the || statement is short-circuited by when the first method evaluates to true.

It is possible to remove the short-circuit in C# by using the bitwise & and | operators instead of the Boolean && and || operators.

private void Form_Load()
{
	if (GetFalse() & GetTrue())
	{
		...
	}
	else
	{
		...
	}

	if (GetTrue() | GetFalse())
	{
		...
	}
	else
	{
		...
	}
}

In this case, both message boxes will be shown because the bitwise operators will evaluate both sides of the expression regardless of their value.

The VBUC will use the standard && and || operators for Boolean logic, despite this known difference, because it is standard practice and using bitwise operators for Boolean logic may be confusing to others reviewing the code.

After migration, when encountering an instance where short-circuiting is affecting code flow, the way to fix it should be done on a case-by-case basis, using either the bitwise operators, or evaluating the conditions beforehand, as in the following example.

private void Form_Load()
{
	bool value1 = GetFalse();
	bool value2 = GetTrue();
	if (value1 && value2)
	{
		...
	}
	else
	{
		...
	}

	bool value3 = GetTrue();
	bool value4 = GetFalse();
	if (value3 || value4)
	{
		...
	}
	else
	{
		...
	}
}

Last updated