我有一个需要验证的项目列表。该列表可以包含任意数量的A,B和C类型的项目,但在保存列表之前,它必须符合以下规则:
我最终得到了以下代码(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可能会三次迭代列表 这个if对我来说不好看。
原因是使用不同的变量名称并将测试提取到具有良好名称的方法会更好,但我认为有更好的方法可以完全解决这个问题。我只是不确定......
任何提示?
答案 0 :(得分:3)
我会使用一个简单的循环,既可以理解又有效。
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);
答案 1 :(得分:2)
如果您只浏览一次列表非常重要,那么您可以这样做:
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被正确命名(类似于hasNotifyEmail
或needsResponse
,这就解释了为什么你希望它们使用指定的规则),那么其他人应该很容易理解。
答案 2 :(得分:-1)
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;