Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中检查三个具有某些值或全部为空的属性的更好方法#_C# - Fatal编程技术网

C# 在C中检查三个具有某些值或全部为空的属性的更好方法#

C# 在C中检查三个具有某些值或全部为空的属性的更好方法#,c#,C#,对象中有三个属性 {obj.prop1, obj.prop2, obj.prop3} These properties are NULLABLE INTEGER 我需要验证这三个属性是否都应该包含一些值,或者这三个属性都是null 这是验证 if (!((!obj.prop1.HasValue && !obj.prop2.HasValue && !obj.prop3.HasValue) || (obj.prop1.HasValue

对象中有三个属性

{obj.prop1, obj.prop2, obj.prop3} These properties are NULLABLE INTEGER
我需要验证这三个属性是否都应该包含一些值,或者这三个属性都是null

这是验证

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 ?? obj.prop2 ?? obj.prop3) == null 
   || (obj.prop1.HasValue && obj.prop2.HasValue && obj.prop3.HasValue)) 
{
   // conditional block
}

但是,我认为对于普通用户来说,您的原始方式更容易理解。

您可以使用空合并进行空检查,但您仍然需要验证是否所有项都确实具有其他项的值:

if((obj.prop1 ?? obj.prop2 ?? obj.prop3) == null 
   || (obj.prop1.HasValue && obj.prop2.HasValue && obj.prop3.HasValue)) 
{
   // conditional block
}

但是,我认为普通用户更容易理解最初的方法。

我不知道有哪种逻辑运算符可以使代码看起来更好,但我经常做的是将功能包装到一个方法中,并使用一个名称来描述测试。这有助于减少代码大小,并使代码“自文档化”

下面是一个示例方法,它将测试一组对象,看看它们是否“部分为空”

私有静态布尔值为partiallynull(参数对象[]值)
{

if(values.Length我不知道有哪种逻辑运算符可以使代码看起来更好,但我经常做的是将功能包装到一个名称描述测试的方法中。这有助于减少代码大小,并使代码“自文档化”

下面是一个示例方法,它将测试一组对象,看看它们是否“部分为空”

私有静态布尔值为partiallynull(参数对象[]值)
{
如果(values.Length,您可以尝试此方法

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
你可以试试这个

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

实际上,根据您在为对象添加新属性时所希望的“自动”程度,有几种方法可以实现这一点。如果您不介意在每次添加新属性时更新您的检查,我将使用一种简单的方法进行比较

首先,您提供的示例是一种很好的方法。这实际上是执行检查的最有效的方法。缺点是它过于冗长,如果您计划向对象添加更多属性,则无法很好地扩展

你可以考虑的下一个方法是创建一个自定义函数,它比较你的属性。这样,当你使用代码中的函数时,它就没有那么冗长了。下面的函数将占用你想要的多个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;
}

我建议的最后一个选项是使用反射。使用反射,您可以循环属性,并使用与上述函数类似的逻辑检查每个属性。这种方法的好处是,您不需要在添加新属性时调整逻辑。缺点是性能。

实际上有几种方法s您可以根据您在为对象添加新属性时希望的“自动”程度来执行此操作。如果您不介意在每次添加新属性时更新您的检查,我将使用一个简单的方法进行比较

首先,您提供的示例是一种很好的方法。这实际上是执行检查的最有效的方法。缺点是它过于冗长,如果您计划向对象添加更多属性,则无法很好地扩展

你可以考虑的下一个方法是创建一个自定义函数,它比较你的属性。这样,当你使用代码中的函数时,它就没有那么冗长了。下面的函数将占用你想要的多个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;
}

我建议的最后一个选项是使用反射。使用反射,您可以循环属性,并使用与上述函数类似的逻辑检查每个属性。这种方法的好处是,您不需要在添加新属性时调整逻辑。缺点是性能。

如果您只想确保所有三个都有值或没有值(不管值是什么)


如果您只是想确保这三个都有值或没有值(无论值是什么),那么


这种方式有什么问题?
如果(obj.prop1.HasValue!=obj.prop2.HasValue | | obj.prop2.HasValue!=obj.prop3.HasValue)抛出…
@roryap看起来很困惑,我想知道是否有其他逻辑运算符可以让其他人更容易阅读和理解。这种方式有什么问题?
如果(obj.prop1.HasValue!=obj.prop2.HasValue | | obj.prop2.HasValue!=obj.prop3.HasValue)抛出…
@roryap看起来很困惑,我想知道是否还有其他逻辑运算符可以让其他人更容易阅读和理解。整个块不应该包装在NOT(!)中吗block?我可以补充一下,但我只是展示了空合并运算符的用法。是的,我明白你所说的。看看上面的Zdeslav Vojkovic答案,看起来很棒。同意,他已经在你的问题的评论中提到了这一点,所以我不想看起来像是在讽刺他的答案,但我想至少provide另一个选项。=)整个块不应该包装在一个非(!)block?我可以补充一下,但我只是展示了空合并运算符的用法。是的,我明白你所说的。看看上面的Zdeslav Vojkovic答案,看起来很棒。同意,他已经在你的问题的评论中提到了这一点,所以我不想看起来像是在讽刺他的答案,但我想至少p提供另一个选项。=)顺便问一句,你在哪里生成的漂亮的门图?你是手工制作的还是有任何工具可供使用