0

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);
    }
}
3
  • Your last code section will also hit the NRE as the ServersHolder.Servers is not handled with the null checking. Commented Apr 5, 2024 at 4:00
  • As you mention ServersHolder.Servers could be null, I doubt you will get the Null Reference Exception in the loop if it is null. Thus you have to provide a default value when it is null with empty IEnumerable<YourType> foreach (var user in ServersHolder.Servers?.Find(f => f.ID == 9999).Online?.FindAll(g => g.LoginPhase == 3) ?? new List<User>) Commented Apr 5, 2024 at 4:06
  • @Yong Shun that is what I'm looking for. I'm getting this error: Operator '??' cannot be applied to operands of type 'List<OnlineModel>' and 'method group', so this is actually checking to see if the Online.FindAll is null, instead of the ServersHolder.Servers, (Online is the online user class in a list) Commented Apr 5, 2024 at 4:12

1 Answer 1

1

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:

  1. Validate ServersHolder.Servers is not null.
  2. Validate existence of the record with ID = 9999 in ServersHolder.Servers.
  3. The Online property after the (2) cannot be null.
  4. Filter all the records in the 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);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.