提问人:Yair Halberstadt 提问时间:8/23/2019 更新时间:8/23/2019 访问量:344
n 个字段中最多有一个字段不为 null
At most one field out of n is not null
问:
我在一个类中有 n 个字段。最多允许设置其中一个,因此如果不是这种情况,我需要抛出异常。我知道 n 的值。
我可以用显而易见的方式做到这一点:
if (field1 != null && (field2 != null || field3 != null ||...)
|| field2 != null && (field1 != null || field3 != null ||...)
...)
throw new Exception();
但是,在字段数量中,它的长度是 n^2,我绝对不想为此写出来。10 个字段。
我看到建议通过反思来做到这一点。然而,虽然在你不知道 n 的值的情况下这是必要的,但我不禁认为这里一定有一种更简单的方法。
那么有没有办法检查 n 个值中最多是否有一个不是 null,而每个值只访问一次?
答:
0赞
Yair Halberstadt
8/23/2019
#1
public int NotNullToOne<T>(T val) => val is null ? 0 : 1;
if (NotNullToOne(field1) + NotNullToOne(field2) + NotNullToOne(field3) + ... > 1)
throw new Exception();
如果值不为 null,则返回 NotNullToOne,如果值为 o,则返回 o。
如果多个值为 null,则所有 s 的总和将大于 1,因此将引发。NotNullToOne
评论
1赞
Lasse V. Karlsen
8/23/2019
在他的问题代码中,他检查了每个字段的组合,即。“9 个 ok 字段 + 1 个 null”,然后是“8 个 ok 字段 + 1 个 null + 1 个 ok 字段”,等等。这个计算 OK 字段并检查。
0赞
Yair Halberstadt
8/23/2019
这在字段数量上是线性的,而不是二次的。
0赞
MrSmith42
8/23/2019
这正是 Lasse Vågsæther Karlsen 在对您的问题的评论中提到的。
0赞
Yair Halberstadt
8/23/2019
@MrSmith42 是的。我碰巧想到了这一点并写下了这个答案,而他则写了那条评论。
2赞
mihai.luca
8/23/2019
#2
您可以有一个计数器来表示设置了多少个字段。
int numberOfSetFields = 0;
if (field1 != null)
numberOfSetFields++;
if (field2 != null)
numberOfSetFields++;
if (field3 != null)
numberOfSetFields++;
...
if (numberOfSetFields > 1)
{
throw new Exception();
}
或者,如果已设置至少 1 个以上的字段,则可以使用属性不再检查其他字段
int numberOfSetFields = 0;
int NumberOfSetFields
{
get { return numberOfSetFields; }
set
{
numberOfSetFields = value;
if (numberOfSetFields > 1)
throw new Exception();
}
}
if (field1 != null)
NumberOfSetFields++;
if (field2 != null)
NumberOfSetFields++;
if (field3 != null)
NumberOfSetFields++;
...
NumberOfSetFields 属性的 set 方法将检查是否至少有 1 个设置字段。这样,假设您有 10 个字段,并且设置了前 2 个字段,那么与我提到的第一种方法相比,其他 8 个字段将不再被检查。
1赞
Peter B
8/23/2019
#3
可以使用具有描述性名称的帮助程序方法,以便在调用端更清楚地显示您尝试检查的内容,如下所示:
public static bool MoreThanOneNotNull<T>(params T[] items)
{
int count = 0;
for (int i = 0; i < items.Length; i++)
if (items[i] is object && ++count > 1)
return true;
return false;
}
用法:
if (MoreThanOneNotNull(field1, field2, field3, field4, ... ))
// ...
评论
0赞
Yair Halberstadt
8/23/2019
我认为这样做的缺点是它不必要地分配了一个数组,但在许多情况下,这将是一个不成熟的优化,而且它肯定比我的解决方案更清晰。
评论