- What language is this for?
C# (.NET 7) - Which rule?
S2589 - Are you using
SonarLint 7.3.0.77872 on Visual Studio 2022 17.4.4 (not connected)
I noticed a case of a switch expression not getting correctly interpreted when using an enum.
Consider the following minimal reproduction:
using System;
namespace Test;
public enum UserType
{
Internal,
External,
Other
}
public interface IUser
{
int Id { get; }
string LoginName { get; }
UserType UserType { get; }
}
public static class Program
{
public static void Check_SwitchExpression(IUser user)
{
if (user.UserType switch
{
UserType.Internal => user.Id == 1,
UserType.External => user.LoginName == "test",
_ => false,
})
return;
throw new ApplicationException("not authorized");
}
public static void Check_SwitchStatement(IUser user)
{
switch (user.UserType)
{
case UserType.Internal:
if (user.Id == 1) return;
break;
case UserType.External:
if (user.LoginName == "test") return;
else break;
}
throw new ApplicationException("not authorized");
}
public static void Main()
{
// ignore this
}
}
The method Check_SwitchExpression
raises the following report:
S2589: Change this condition so that it does not always evaluate to ‘False’
Note that changing the final default branch to true
makes the rule say the opposite.
Unless I am missing something, the two Check methods should be logically equivalent.
For further reference here is a decompiled version of the code:
// Decompiled with JetBrains decompiler
// Type: Test.Program
// Assembly: MiscTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
using System;
namespace Test
{
public static class Program
{
public static void Check_SwitchExpression(IUser user)
{
UserType userType = user.UserType;
if (true)
;
bool flag;
switch (userType)
{
case UserType.Internal:
flag = user.Id == 1;
break;
case UserType.External:
flag = user.LoginName == "test";
break;
default:
flag = false;
break;
}
if (true)
;
if (!flag)
throw new ApplicationException("not authorized");
}
public static void Check_SwitchStatement(IUser user)
{
switch (user.UserType)
{
case UserType.Internal:
if (user.Id == 1)
return;
break;
case UserType.External:
if (user.LoginName == "test")
return;
break;
}
throw new ApplicationException("not authorized");
}
public static void Main()
{
}
}
}