Fix #3702: Don't rewrite GetValueOrDefault() to == true in ?. chains
Turning bool?.GetValueOrDefault() into `== true` ends an enclosing null-conditional chain, so `c?.Flag.GetValueOrDefault()` became `(c?.Flag == true)` of type bool instead of bool?. A following `?? false` then fails to compile (CS0019), and a following `.ToString()` yields "False" instead of null when c is null. Keep the call when its target is part of a ?. chain.
This commit is contained in:
1 parent
8e3e41fedb
commit
ffe7e7b3f1
4 files changed
+37
-2
No files matched your search
@@ -26,6 +26,7 @@ using System.Text;
|
||||
|
||||
using ICSharpCode.Decompiler.CSharp.Resolver;
|
||||
using ICSharpCode.Decompiler.CSharp.Syntax;
|
||||
using ICSharpCode.Decompiler.CSharp.Transforms;
|
||||
using ICSharpCode.Decompiler.IL;
|
||||
using ICSharpCode.Decompiler.IL.Transforms;
|
||||
using ICSharpCode.Decompiler.Semantics;
|
||||
@@ -594,7 +595,8 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
if (settings.LiftNullables && method.Name == "GetValueOrDefault"
|
||||
&& method.DeclaringType.IsKnownType(KnownTypeCode.NullableOfT)
|
||||
&& method.DeclaringType.TypeArguments[0].IsKnownType(KnownTypeCode.Boolean)
|
||||
&& argumentList.Length == 0)
|
||||
&& argumentList.Length == 0
|
||||
&& !IntroduceQueryExpressions.IsNullConditional(target))
|
||||
{
|
||||
argumentList.CheckNoNamedOrOptionalArguments();
|
||||
return new BinaryOperatorExpression(
|
||||
|
||||
@@ -380,7 +380,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
||||
}
|
||||
}
|
||||
|
||||
bool IsNullConditional(Expression target) => target switch {
|
||||
internal static bool IsNullConditional(Expression target) => target switch {
|
||||
UnaryOperatorExpression { Operator: UnaryOperatorType.NullConditional } => true,
|
||||
MemberReferenceExpression member => IsNullConditional(member.Target),
|
||||
InvocationExpression invocation => IsNullConditional(invocation.Target),
|
||||
|
||||
Reference in new issue
Block a user