Reputation: 651
I have that code:
List<Move> list = new List<Move>();
list.Add(GetBeatingForFieldOnSpecificDiagonal(i, enemyColor, Constant.TOP_LEFT));
list.Add(GetBeatingForFieldOnSpecificDiagonal(i, enemyColor, Constant.TOP_RIGHT));
list.Add(GetBeatingForFieldOnSpecificDiagonal(i, enemyColor, Constant.DOWN_LEFT));
list.Add(GetBeatingForFieldOnSpecificDiagonal(i, enemyColor, Constant.DOWN_RIGHT));
The question is:
Is this possible to somehow check if this element is not null before add it to the list?
I mean I don't want to call that method twice. One call for check it is not null and another for eventually add it, this is a bad way, because I am writing an AI algorithm for computer and any resources are important.
Upvotes: 0
Views: 3314
Reputation: 112334
Solution 1:
Use the Try... out var -pattern.
private bool TryGetHitForFieldOnDiagonal(int i, Color enemyColor, Constant constant,
out Move move)
{
// pesudo code
if (finds_a_diagonal) {
move = get_some_move;
return true;
}
move = null;
return false;
}
Then
if (TryGetHitForFieldOnDiagonal(i, enemyColor, Constant.TOP_LEFT, out var m)) list.Add(m);
if (TryGetHitForFieldOnDiagonal(i, enemyColor, Constant.TOP_RIGHT, out m)) list.Add(m);
if (TryGetHitForFieldOnDiagonal(i, enemyColor, Constant.DOWN_LEFT, out m)) list.Add(m);
if (TryGetHitForFieldOnDiagonal(i, enemyColor, Constant.DOWN_RIGHT, out m)) list.Add(m);
Solution 2:
Use C#8.0 pattern matching and loop over the constants:
foreach (Constant c in Enum.GetValues(typeof(Constant))) {
if (GetHitForFieldOnDiagonal(i, enemyColor, c) is { } move) list.Add(move);
}
The pattern { } move
is an empty property pattern. It tests whether the returned value is not null and binds the result to the new variable move
.
Solution 3:
The loop of solution 2 assumes that you want to loop over all the constants. If you don't want to do this, you can instead use this pattern matching four times.
if (GetHitForFieldOnDiagonal(i, enemyColor, Constant.TOP_LEFT) is { } m1) list.Add(m1);
if (GetHitForFieldOnDiagonal(i, enemyColor, Constant.TOP_RIGHT) is { } m2) list.Add(m2);
if (GetHitForFieldOnDiagonal(i, enemyColor, Constant.DOWN_LEFT) is { } m3) list.Add(m3);
if (GetHitForFieldOnDiagonal(i, enemyColor, Constant.DOWN_RIGHT) is { } m4) list.Add(m4);
Solution 4:
In C#8.0, you can also declare local functions, i.e., methods embedded within other methods.
void AddNonNullHitToList(Constant constant) // local function
{
if (GetHitForFieldOnDiagonal(i, enemyColor, constant) is { } m) list.Add(m);
}
AddNonNullHitToList(Constant.TOP_LEFT);
AddNonNullHitToList(Constant.TOP_RIGHT);
AddNonNullHitToList(Constant.DOWN_LEFT);
AddNonNullHitToList(Constant.DOWN_RIGHT);
Note that this local function has access to the variables of the surrounding method (here i
, enemyColor
and list
).
Upvotes: 1
Reputation: 218837
The simplest approach is probably to just filter the list for non-null elements after adding them:
list = list.Where(l => l != null);
or possibly:
list = list.Where(l => l != null).ToList();
to materialize it to a List<>
immediately, since list
is explicitly a list type.
Upvotes: 3
Reputation: 311188
You can store the value into a variable, check if it's null, and then add it to the list:
Move tmp = GetBeatingForFieldOnSpecificDiagonal(i, enemyColor, Constant.TOP_LEFT);
if (tmp != null) {
list.Add(tmp);
}
// The same can (should?) be done for the other moves
Upvotes: 1