检查列表中的项目的有效组合

本文关键字:有效 组合 项目 检查 列表 | 更新日期: 2023-09-27 18:32:08

我有一个需要验证的项目列表。列表可以包含任意数量的 A、B 和 C 类型的项目,但在保存列表之前,它必须确认以下规则:

  1. 如果你有 A,你需要 B 或 C
  2. 如果你有 B,你需要 A

我最终得到了以下代码(saudo 代码):

bool IsListValid()
{
  var a = list.ContainsAny(A);
  var b = list.ContainsAny(B);
  var c = list.ContainsAny(C);
  if (!a && !b)
    return true;
  if (a && (b || c)
    return true;
  return false;
}

我不喜欢这段代码。
1. 连续使用 Any 三次可能会迭代列表三次
2.如果对我来说并不好看。

当然,使用不同的变量名称并将测试提取到具有良好名称的方法中会更好,但我认为有更好的方法来完全解决这个问题。我只是不确定如何...

有什么提示吗?

检查列表中的项目的有效组合

我会

使用一个简单的循环,它既易于理解又高效。

bool containsA = false, containsB = false, containsC = false;
for (int i = 0; i < list.Count; i++)
{
    Type itemType = list[i].GetType();
    if (!containsA) containsA = itemType == typeof(A);
    if (!containsB) containsB = itemType == typeof(B);
    if (!containsC) containsC = itemType == typeof(C);
    if (containsA && (containsB || containsC)) return true;
}
return (!containsA && !containsB);

如果它非常重要,以至于您只浏览一次列表,您可以这样做:

bool a = false;
bool b = false;
bool c = false;
foreach(var x in list)
{
  if (x is A) a = true;
  if (x is B) b = true;
  if (x is C) c = true;
}

但我会保持原样。如果稍后的性能分析显示此代码正在成为瓶颈,则可以重新访问它。

至于if's,这对我来说看起来不错。只要 A、B 和 C 的名称正确(例如 hasNotifyEmailneedsResponse ,可以解释为什么您希望它们使用指定的规则),那么其他人应该很容易理解。

var hasA = list.Any(x => x.GetType() == typeof(A));
var hasB = list.Any(x => x.GetType() == typeof(B));
var hasC = list.Any(x => x.GetType() == typeof(C));
//If you have A, you need either B or C
// A AND (B xor C)
if (hasA && (hasB ^= hasC))
   return true;
//If you have B, you need A
if (hasB && hasA)
   return true;
   return false;