Compiler has complaint - see code
private ConcurrentQueue<RuleContext> _queue = new ConcurrentQueue<RuleContext>();
public void Add(RuleContext ruleContext)
{
if (ruleContext == null) return;
_logQueue.Enqueue(ruleContext);
}
void Do()
{
while (_logQueue.TryDequeue(out RuleContext ruleCtx)) // <-- converting to non-nullable type
{ .... }
}
now, when I change that to TryDequeue(out RuleContext? ruleCtx)
it calms down.
Question. If type is now RuleContext?
, why in the while
block I don't get a warning when dereference it like ruleCtx.HasLogMessages
??
HasLogMessages
defined as
public bool HasLogMessages {get => true;}
out
parameter of ConcurrentQueue.TryDequeue
is marked with [MaybeNullWhen(false)]
attribute (which does make sense because in case of false
the parameter would be initialized to the default value) and RuleContext
seems to be a reference type (for value types everything would be fine), hence the complaint. Just change the type to RuleContext?
or var
and that's it:
void Do()
{
while (_logQueue.TryDequeue(out RuleContext? ruleCtx)) // or out var ruleCtx
{
Console.WriteLine(ruleCtx.GetType()); // no warning
}
}
No warning inside the while block is due to the compiler being able to correctly perform static flow analysis for nullable references types in this case (hence we can be inside the while only if true
is returned and the attribute warns about nulls only in case of false
being returned, see the Attributes for null-state static analysis interpreted by the C# compiler article).