So I have this code:
foreach (var user in ServersHolder.Servers.Find(f => f.ID == 9999).Online.FindAll(g => g.LoginPhase == 3))
{
await trySendPacket(9999, user.GUID.ToString(), OpCode.SentNotifyUserLeft, "", 2);
}
And I have seen where people use ?.
, I believe in case of a null return like below, but the below doesn't work in that case.
foreach (var user in ServersHolder.Servers?.Find(f => f.ID == 9999).Online?.FindAll(g => g.LoginPhase == 3))
{
await trySendPacket(9999, user.GUID.ToString(), OpCode.SentNotifyUserLeft, "", 2);
}
Could somebody expain? Or is it best practice to do it this way:
if (ServersHolder.Servers.Exists(f => f.ID == 9999))
{
foreach (var user in ServersHolder.Servers.Find(f => f.ID == 9999).Online.FindAll(g => g.LoginPhase == 3))
{
await trySendPacket(9999, user.GUID.ToString(), OpCode.SentNotifyUserLeft, "", 2);
}
}
In the second code section, you perform the null checking for the ServersHolder.Servers
.
In the last code section, you validate there is any matching record in the ServersHolder.Servers
.
Both are performing different validation.
To summarize the validation & data grabbing logic that you needed:
ServersHolder.Servers
is not null.ID = 9999
in ServersHolder.Servers
.Online
property after the (2) cannot be null.Online
property.As mentioned in the comment, you will get the Null Reference Exception (NRE) as you do not handle the null value in the foreach
loop. You need to provide the default/empty list if the chain (with ?.
null-checking operator) returns null
.
foreach (var user in ServersHolder.Servers
?.Find(f => f.ID == 9999)
?.Online
?.FindAll(g => g.LoginPhase == 3) ?? new List<OnlineModel>())
{
await trySendPacket(9999, user.GUID.ToString(), OpCode.SentNotifyUserLeft, "", 2);
}