![](/img/trans.png)
[英]C# is there any better way to check if more than 2 properties in an object is not null
[英]Better way to check three properties having some value or all of them are NULL in C#
对象中有三个属性
{obj.prop1, obj.prop2, obj.prop3} These properties are NULLABLE INTEGER
而且我需要验证所有三个属性都应包含某个值,或者所有三个属性都为空。
这是验证
if (!((!obj.prop1.HasValue && !obj.prop2.HasValue && !obj.prop3.HasValue) ||
(obj.prop1.HasValue && obj.prop2.HasValue && obj.prop3.HasValue)))
{
//throw new Exception("");
}
还有其他更好的方法可以通过其他逻辑运算符来实现吗?
你可以试试这个
if (obj.prop1.HasValue != obj.prop2.HasValue || obj.prop2.HasValue != obj.prop3.HasValue)
throw...
上面的表达式产生:
p1.HasValue p2.HasValue p3.HasValue
==========================================================================
false false false => false || false => false
false false true => false || true => true
false true false => true || true => true
true false false => true || false => true
false true true => true || false => true
true true false => false || true => true
true false true => true || true => true
true true true => false || false => false
您可以对null检查使用null合并,但是您仍然需要验证所有项目是否确实具有另一个项目的值:
if((obj.prop1 ?? obj.prop2 ?? obj.prop3) == null
|| (obj.prop1.HasValue && obj.prop2.HasValue && obj.prop3.HasValue))
{
// conditional block
}
但是,我认为普通用户更容易理解原始的方式。
我不知道可以使代码看起来更好的逻辑运算符,但是我经常做的就是将功能包装到一个描述测试的名称的方法中。 这有助于减小代码大小,并使代码“自我记录”。
这是一个示例方法,它将测试一堆对象以查看它们是否“部分为空”。
private static bool ArePartiallyNull(params object[] values)
{
if(values.Length <= 1)
return false;
var isNull = values[0] == null;
for(var i = 1;i < values.Length;i++)
{
if(isNull != (values[i] == null))
return true;
}
return false;
}
而这种方法正在起作用: https : //dotnetfiddle.net/6QIpDF
public class Program
{
public static void Main()
{
int? one = 1;
int? two = 1;
int? three = 1;
int? nullOne = null;
int? nullTwo = null;
int? nullThree = null;
Console.WriteLine(ArePartiallyNull(one, two, three));
Console.WriteLine(ArePartiallyNull(nullOne, nullTwo, nullThree));
Console.WriteLine(ArePartiallyNull(one, two, nullThree));
}
private static bool ArePartiallyNull(params object[] values)
{
if(values.Length <= 1)
return false;
var isNull = values[0] == null;
for(var i = 1;i < values.Length;i++)
{
if(isNull != (values[i] == null))
return true;
}
return false;
}
}
实际上,有几种方法可以解决此问题,具体取决于您在为对象添加新属性时希望它的“自动”程度。 如果您不介意每次添加新属性时都更新支票,那么我将使用一种简单的比较方法。
首先,您提供的示例是一种很好的方法。 实际上,这将是执行检查的最有效方式。 缺点是它过于冗长,如果计划向该对象添加更多属性,则扩展性不好。
您可以考虑的下一个方法是创建一个自定义函数,为您比较属性。 这样,当您在代码中使用该函数时,它就不再那么冗长。 下面的函数需要多少个int? 您想扔给它的变量,并验证它们是否都具有值或没有值。
bool Test(params int?[] props)
{
bool? lastValue = null;
foreach(int? p in props)
{
// We haven't got a status yet so we just use the status for the first prop
if (lastValue.HasValue == false)
lastValue = p.HasValue;
else
{
// If the status of this next prop doesn't match the first, we know it is false
if (p.HasValue != lastValue.Value)
return false;
}
}
// Default back to true since we didn't identify any issues.
return true;
}
我建议的最后一个选择是使用反射。 通过反射,您可以遍历属性并使用与上述函数类似的逻辑来检查每个属性。 这种方法的好处是您在添加新属性时无需调整逻辑。 缺点是性能。
如果您只是要确保所有三个值都有或没有值(不管值是什么),则
bool AllAreTrueOrFalse(params bool[] values)
{
return values.All(value=>value) || !values.Any(value=>value);
}
var allTrueOrFalse = AllAreTrueOrFalse(obj.prop1.HasValue, obj.prop2.HasValue,
obj.prop3.HasValue);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.