Files
icsharpcode-ILSpy/ICSharpCode.Decompiler.Tests/TestCases/Correctness/NullPropagation.cs
T
dualfroz ffe7e7b3f1 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.
2026-10-16 10:07:54 +02:00

86 lines
1.9 KiB
C#

using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{
class NullPropagation
{
static void Main()
{
new NullPropagation().TestNotCoalescing();
new NullPropagation().TestNullableBoolInChain();
#if CS72
new NullPropagation().TestRefStructNotCoalescing();
#endif
}
class MyClass
{
public string Text;
public bool? Flag;
}
void TestNotCoalescing()
{
Console.WriteLine("TestNotCoalescing:");
Console.WriteLine(NotCoalescing(null));
Console.WriteLine(NotCoalescing(new MyClass()));
}
string NotCoalescing(MyClass c)
{
return c != null ? c.Text : "Hello";
}
void TestNullableBoolInChain()
{
Console.WriteLine("TestNullableBoolInChain:");
foreach (MyClass c in new[] { null, new MyClass(), new MyClass { Flag = false }, new MyClass { Flag = true } })
{
Console.WriteLine(EqualsTrue(c));
Console.WriteLine(GetValueOrDefaultToString(c) ?? "<null>");
}
}
bool EqualsTrue(MyClass c)
{
return c?.Flag == true;
}
string GetValueOrDefaultToString(MyClass c)
{
return c?.Flag.GetValueOrDefault().ToString();
}
#if CS72
ref struct ByRefLikeStruct
{
public int Value;
}
class RefStructHolder
{
public ByRefLikeStruct Get()
{
ByRefLikeStruct result = default(ByRefLikeStruct);
result.Value = 42;
return result;
}
}
void TestRefStructNotCoalescing()
{
Console.WriteLine("TestRefStructNotCoalescing:");
Console.WriteLine(RefStructNotCoalescing(null).Value);
Console.WriteLine(RefStructNotCoalescing(new RefStructHolder()).Value);
}
// A by-ref-like return type cannot be turned into a ?. / ?? null-propagation: a ref struct
// cannot be wrapped in Nullable<T>, so that form does not compile.
ByRefLikeStruct RefStructNotCoalescing(RefStructHolder holder)
{
return holder != null ? holder.Get() : default(ByRefLikeStruct);
}
#endif
}
}