即使在结果返回 true 后,在使用 or 运算符时调用所有 3 个函数

Posted

技术标签:

【中文标题】即使在结果返回 true 后,在使用 or 运算符时调用所有 3 个函数【英文标题】:Calling all the 3 functions while using or operator even after returning true as a result 【发布时间】:2011-02-09 16:29:39 【问题描述】:

我在我的代码中调用三个函数,我想验证我的一些字段。 当我尝试使用下面给出的代码时。它只检查第一个值,直到它得到错误的结果。

我想要这样的东西,如果第一个函数返回 true,那么它也应该调用下一个函数等等。可以使用什么来代替 Or Operator 来做到这一点。

    if (IsFieldEmpty(ref txtFactoryName, true, "Required") ||
        IsFieldEmpty(ref txtShortName, true, "Required") ||
        IsFieldEmpty(ref cboGodown, true, "Required"))
     

编辑

public bool IsFieldEmpty(ref TextBox txtControl, Boolean SetErrorProvider,string msgToShowOnError)

    ErrorProvider EP = new ErrorProvider();
    if (txtControl.Text == string.Empty)
    
        EP.SetError(txtControl, msgToShowOnError);
        return true;
    
    else
    
        EP.Clear();
        return false;
    

请评论,使用 ref 变量作为参数之一是否可以使用此方法。

我正在检查winform 中的onSubmit 事件的验证。

【问题讨论】:

我可能是错的,但除此之外,您似乎在滥用 ErrorProvider。您可能应该有一个实例作为表单成员,而不是在每次验证时都旋转一个新的。 【参考方案1】:

您可以将单个 | 用于 OR:

 if (IsFieldEmpty(ref txtFactoryName, true, "Required") |
    IsFieldEmpty(ref txtShortName, true, "Required") |
    IsFieldEmpty(ref cboGodown, true, "Required"))
 

双管|| 执行short-circuit evaluation,single version | 进行全面评估。&&& 也是如此。

请参阅MSDN reference。

编辑的回应:

    txtControl 前面不需要“ref”,删除它将大大有助于解决对您的方法的批评。 IsFieldEmpty 不对 txtControl 进行任何更改。您可以重命名为 CheckFieldEmpty 以进一步改进它。 奇怪的是,您在此方法中创建了一个 ErrorProvider 实例,这是否有效?表单上通常应该有一个(永久)实例。您可能希望此方法独立于 Form,因此只需添加一个 EP 作为参数。它可以代替 SetErrorProvider,可以检查 EP 参数是否为空。 O,将EP.Clear(); 替换为Ep.SetErrortxtControl, "");

【讨论】:

单个字符|是按位运算。你是对的,它不会短路,在这种情况下它会做你想做的事,但是很糟糕。 错了,|& 运算符都是按位和逻辑的,具体取决于操作数,因此将它们用于逻辑运算也是完全合法的。是的,短路也不是。有关文档,请查看 msdn.microsoft.com/en-us/library/6a71f45d(VS.71).aspx。如果它们只是按位,则表达式不会编译,因为没有自动转换为 bool,所以 if 语句将是 if (int) @Richiel:不,我正在寻找官方链接,但| 也绝对被定义为布尔运算符。 (已添加链接) 似乎很容易误读该代码的意图。 @Scott,我同意你的观点,很容易错过缺少的| 字符。【参考方案2】:

明确说明你在做什么:

bool isFactoryNameEmpty = IsFieldEmpty(ref txtFactoryName, true, "Required");
bool isShortNameEmpty = IsFieldEmpty(ref txtShortName, true, "Required");
bool isGodownEmpty = IsFieldEmpty(ref cboGodown, true, "Required");
if (isFactoryNameEmpty || isShortNameEmpty || isGodownEmpty)

    // ...

(另外,我假设您需要调用所有三个函数,因为它们有副作用?在这种情况下,IsFieldEmpty 是一个非常糟糕的名字。)

【讨论】:

我强烈推荐这种方法。据推测,您想避免短路,因为您的方法有副作用。调用这些方法不仅仅是为了查询状态。在这种情况下,将方法调用混合到 if 语句中会隐藏进行方法调用的全部意图。 -1 这增加了一堆无用的文本,在不改变功能的情况下损害了可读性。 Henk 的解决方案更具可读性。存在短路和非短路逻辑运算符是有原因的。 @Adam:我认为您必须在| 解决方案上方添加的精彩评论会更损害可读性,解释为什么您使用| 而不是更明显||。 (当然,重命名 IsFieldEmpty 在这两种情况下都会有所帮助!) @Adam:goto 声明还有一个原因。这并不意味着它的使用没有危险。 调用一个看起来像简单布尔测试的函数 IsFieldEmpty 很重要,这似乎有些可疑。它表明此功能正在做其他事情,例如记录正在进行的测试。就个人而言,我会选择更长的版本,因为您不太可能欺骗团队中的任何其他开发人员了解正在发生的事情。单|版本已经成熟,容易被误解。【参考方案3】:

你为什么需要它?我能想到的唯一原因是您的“IsFieldEmpty”函数也在对数据进行一些计算或更改,这让我很担心。一个名为“IsFieldEmpty”的函数真的不应该做任何其他事情。

在这种情况下,从可用性/可维护性的角度来看,您最好:

SomeFieldMaintenance(ref txtFactoryName, true, "Required")
SomeFieldMaintenance(ref txtShortName, true, "Required")
SomeFieldMaintenance(ref cboGodown, true, "Required")
if (IsFieldEmpty(txtFactoryname) ||
    IsFieldEmpty(txtShortName) ||
    IsFieldEmpty(cboGodown))
 

或类似的东西。

【讨论】:

我同意该函数可以更恰当地命名,但为什么要附加函数(尤其是带有ref 参数)? 我没有重命名,我将其拆分为两个函数。一个是做任何需要的字段维护,一个是检查任何字段是否为空。重命名它可能就足够了,但我们无法知道这一点,因为我们不知道 IsFieldEmpty 函数中发生了什么——只是它所做的事情比标签上所说的要多。但你是对的,在这种情况下,裁判可能应该被移动...... 这是 Refactoring by Martin Fowler 中描述的“从修饰符分离查询”重构的一个很好的例子。 @Treven:我仍然没有看到这里需要 ref 参数。 @Adam 如果您有原始 IsFieldEmpty 函数的副本,请与我们分享。我只是从代码的原始 sn-p 中复制参数。【参考方案4】:

您所看到的在 C# 中称为短路。如果第一个表达式失败,那么它就不会再尝试下一个表达式了,因为最终结果已经确定了。

http://johnnycoder.com/blog/2006/08/02/short-circuit-operators-in-c/

你应该你|而不是 ||得到你的结果。

 if (IsFieldEmpty(ref txtFactoryName, true, "Required") |
        IsFieldEmpty(ref txtShortName, true, "Required") |
        IsFieldEmpty(ref cboGodown, true, "Required"))

C# 运算符 http://msdn.microsoft.com/en-us/library/6a71f45d.aspx

||操作员。 http://msdn.microsoft.com/en-us/library/6373h346.aspx

|操作员。 http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx

【讨论】:

【参考方案5】:

到目前为止的答案都假设您想要验证所有字段,即使其中一个字段失败。这个假设在你原来的问题中并不明确。因此,如果您不介意在某个字段失败时停止验证,那么最简单的解决方案是使用 && 运算符而不是 ||。这将实现您的既定目标:“如果第一个函数返回 true,那么它还应该调用下一个函数,依此类推”。但是,如果第一个函数返回 false,则不会调用其他函数,这可能不是您想要的。

【讨论】:

以上是关于即使在结果返回 true 后,在使用 or 运算符时调用所有 3 个函数的主要内容,如果未能解决你的问题,请参考以下文章

and和or运算

Oracle Or子句

Oracle Or子句

Oracle Or子句

函数调用之间的 OR 运算符

Python逻辑运算符