如何在将元素添加到列表之前检查元素是否为空?
How to check if element is null before add it to list?
我有那个代码:
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));
问题是:
是否可以在将此元素添加到列表之前以某种方式检查它是否不为空?
我的意思是我不想调用那个方法两次。一个要求检查它不为空,另一个要求最终添加它,这是一种糟糕的方式,因为我正在为计算机编写 AI 算法,任何资源都很重要。
最简单的方法可能是在添加非空元素后过滤列表:
list = list.Where(l => l != null);
或者可能:
list = list.Where(l => l != null).ToList();
立即将其具体化为 List<>
,因为 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
解决方案一:
使用 Try...out var 模式。
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;
}
然后
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);
方案二:
使用 C#8.0 模式匹配并遍历常量:
foreach (Constant c in Enum.GetValues(typeof(Constant))) {
if (GetHitForFieldOnDiagonal(i, enemyColor, c) is { } move) list.Add(move);
}
模式 { } move
是空 属性 模式。它测试返回值是否不为 null 并将结果绑定到新变量 move
.
方案三:
解决方案2的循环假定您要遍历所有常量。如果你不想这样做,你可以使用这个模式匹配四次。
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);
方案四:
在 C#8.0 中,您还可以声明局部函数,即嵌入在其他方法中的方法。
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);
请注意,此局部函数可以访问周围方法的变量(此处为 i
、enemyColor
和 list
)。
我有那个代码:
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));
问题是:
是否可以在将此元素添加到列表之前以某种方式检查它是否不为空?
我的意思是我不想调用那个方法两次。一个要求检查它不为空,另一个要求最终添加它,这是一种糟糕的方式,因为我正在为计算机编写 AI 算法,任何资源都很重要。
最简单的方法可能是在添加非空元素后过滤列表:
list = list.Where(l => l != null);
或者可能:
list = list.Where(l => l != null).ToList();
立即将其具体化为 List<>
,因为 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
解决方案一:
使用 Try...out var 模式。
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;
}
然后
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);
方案二:
使用 C#8.0 模式匹配并遍历常量:
foreach (Constant c in Enum.GetValues(typeof(Constant))) {
if (GetHitForFieldOnDiagonal(i, enemyColor, c) is { } move) list.Add(move);
}
模式 { } move
是空 属性 模式。它测试返回值是否不为 null 并将结果绑定到新变量 move
.
方案三:
解决方案2的循环假定您要遍历所有常量。如果你不想这样做,你可以使用这个模式匹配四次。
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);
方案四:
在 C#8.0 中,您还可以声明局部函数,即嵌入在其他方法中的方法。
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);
请注意,此局部函数可以访问周围方法的变量(此处为 i
、enemyColor
和 list
)。