views:

127

answers:

5

I am calling three functions in my code where i want to validate some of my fields. When I tries to work with the code given below. It checks only for first value until it gets false result.

I want some thing like that if fisrt function returns true then it should also call next function and so on. What can be used instead of Or Operator to do this.

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

EDIT

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;
    }
}

Please comment, Is this method fine using ref variable as one of the parameter.

I am checking for validation onSubmit event in winform.

+9  A: 

You can use the single | for OR:

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

The double-pipe || is performing short-circuit evaluation, the single version | does full evaluation.
The same for && and &.

See the MSDN reference.

Response to the Edit:

  1. There is no need for the 'ref' in front of txtControl, and removing that would go a long way in addressing the criticism on your approach here. IsFieldEmpty makes no changes to txtControl. You could rename to CheckFieldEmpty to improve it a little further.
  2. It is strange that you create an ErrorProvider instance inside this method, does that work at all? There should normally be one (permanent) instance on the Form. You probably want this method to be independent of the Form, so just add an EP as a parameter. It can replace the SetErrorProvider, you can check the EP parameter for null. O, and replace EP.Clear(); with Ep.SetErrortxtControl, "");
Henk Holterman
The single character `|` is a bitwise operation. You're right that it doesn't short-circuit, and it will do what you want in this case, but yuck.
RichieHindle
Lasse V. Karlsen
@Richiel: No, I'm looking for an official link but `|` definitely is defined as a boolean operator too. (Links added)
Henk Holterman
seems like it would be real easy to mis-read the intentions of that code.
Scott Weinstein
@Scott, I agree with you on that, easy to miss that missing `|` character.
Lasse V. Karlsen
@Scott - sure, but when you polishing a turd, e.g. IsEmpty w/side effects, everything is going to smell like poo. ;-) Given the code as written this is probably the most elegant solution
Sky Sanders
+10  A: 

Make it explicit what you're doing:

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)
{
    // ...
}

(Also, I assume you need to call all three functions because they have side-effects? In which case IsFieldEmpty is a really bad name.)

RichieHindle
I would strongly recommend this approach. Presumably, you want to avoid the short circuit because your methods have side effects. The methods are not being called simply to query for a state. In that case, mixing the method calls into an if statement hides the full intentions behind making the method calls.
Matthew T. Staebler
-1 This adds a mountain of useless text, hurting readability without changing the functionality. Henk's solution is far more readable; there is a reason that there are both short-circuiting and non-short-circuiting logical operators.
Adam Robinson
@Adam: I think the readability would be hurt more by the socking great comment that you'd have to add above the `|` solution, explaining why you're using `|` rather than the more obvious `||`. (Renaming `IsFieldEmpty` would help in both cases, of course!)
RichieHindle
@Adam: There is also a reason there is a `goto` statement. That does not mean that its use is not perilous.
Matthew T. Staebler
@RichieHindle: I don't think a comment would be necessary if the function were more appropriately named; even so, how would a simple comment be less readable than a bunch of declarations for variables that are only used once?
Adam Robinson
@Aeth: You might be interested to know that a `switch` statement is translated to `goto`'s in IL. An `if` statement is "perilous" in the hands of an incompetent developer; I fail to see how making a distinction between short-circuiting and non-short-circuiting is on the level of using a `goto` in your code; are you saying that people who use both `Or` and `OrElse` in VB are the same?
Adam Robinson
There seems something fishy about it being important to call a function IsFieldEmpty which looks like a simple bool test. It suggests this function is doing something else, like recording what tests are being made. Personally, I would opt for the longer version simply because you're less likely to fool any other devs on your team about what's going on. The single | version is ripe for misinterpretation.
Joel Goodwin
@Adam: I am suggesting nothing of the sort. All that I am suggesting is that the existence of something in the language is not necessarily an endorsement of its use.
Matthew T. Staebler
A: 

What you are seeing is called short circuiting in C#. If the first expression fails, then it won't bother trying the next ones, because the final result has already been determined.

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

You should you | instead of || to get your result.

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

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

|| operator. http://msdn.microsoft.com/en-us/library/6373h346.aspx

| operator. http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx

Kevin
+5  A: 

Why would you need it to? The only reason I can think of is that your "IsFieldEmpty" function is also doing some calculations or changes to the data, and that worries me. A function named "IsFieldEmpty" really shouldn't be doing anything else.

In that case, from a usability/maintainability viewpoint, you'd be better off with:

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

Or something of that ilk.

Trevel
+1 for seeing the wood for the trees!
RichieHindle
I'd agree that the function could be more appropriately named, but why the additional function (especially with a `ref` parameter)?
Adam Robinson
I'm not renaming, I'm splitting it into two functions. One to do whatever field maintenance is required, one to check if any of the fields are empty. It may well be that renaming it would suffice, but we can't know that because we have no idea what is going on in the IsFieldEmpty function -- only that it does something more than what it says on the label. But you're right, under these circumstances, the ref probably should be moved...
Trevel
This is a good example of the "Separate Query from Modifier" refactor as described in [Refactoring by Martin Fowler](http://martinfowler.com/books.html#refactoring).
Matthew T. Staebler
@Treven: I'm still not seeing any need for `ref` parameters here.
Adam Robinson
@Adam If you have a copy of the original IsFieldEmpty function, please, share with the rest of us. I'm just copying the parameters from the original snippet of code.
Trevel
@Trevel: D'oh, indeed you are. My apologies.
Adam Robinson
A: 

The answers so far have assumed that you want to validate all the fields, even after one of them fails. This assumption is not explicit in your original question. So, if you don't mind stopping validation when one field fails, then the simplest solution is to use the && operator instead of ||. This will achieve your stated goal: "if first function returns true then it should also call next function and so on". However, if the first function returns false, then none of the other functions will be called, which may not be what you want.

ShellShock