Hi I have something like:
Version 1:
bool noErrors = true;
while(noErrors)
{
noErrors = ValidateControl(txtName);
// other code
}
Version 2:
bool noErrors = true;
while(noErrors)
{
if(!ValidateControl(txtName)) break;
// other code
}
I use this code to validate a form and if the validation returns false, I want to break before executing "other code". Since I do not know when the loop checks for its condition, I do not know which makes more sense. Should I use the first or the second version, or maybe a third one?
Thank you for your time
Version 2 will break before running the //other code. Version 1 will not check until the start of the next iteration.
bool noErrors = true;
while(noErrors)
{
noErrors = ValidateControl(txtName);
// other code
}
Checks before each iteration.
bool noErrors = true;
do
{
noErrors = ValidateControl(txtName);
// other code
} while(noErrors);
Checks after each iteration.
Neither check during an iteration. As stated by the other answerers, the following code simplifies the example but makes me ask the question, is the validity of txtName likely to change during the execution of the loop? Would some other limiting condition be more useful?
while (ValidateControl(txtName))
{
// other code
}
If the validity of txtName will not change, consider,
if (ValidateControl(txtName))
{
while(/*Some other condition*/)
{
// other code
}
}
The condition is only ever checked at the start of any possible iteration. So in version 1 the "other code" would be executed even if noErrors has been set to false in the first line of the body... whereas in version 2 it wouldn't... but noErrors looks like it's somewhat useless in version 2.
Could you change it to:
while (ValidateControl(txtName))
{
// other code
}
?
A while loop evaluates its condition before the first iteration, and inbetween each subsequent iteration. The condition is never evaluated inside the loop body.
It checks it before running again (first time, after first run and so on). You have to break or whole chunk of code will run.
The while loop checks the condition before it iterates over the block of code that it precedes. You can also make it check the condition at the end by using a do-while construct. Your version #2 will produce the result you desire.
The while loop checks the condition before executing the entire code block. If you want to break execution before the other code is executed, use Version 2.
The loop condition is only evaluated at the start of each loop, so in your first version, the "other code" will still be executed, even if ValidateControl returns false.
Your second version works better, and will not run the "other code" if ValidateControl returns false, however it also does not set noErrors to false if the validation fails. If that's not important, and noErrors is only the loop condition, then you might as well change your while loop to while(true), if it is used later in the code, then you'll need to change version 2 slightly:
bool noErrors = true;
while(noErrors)
{
if(!ValidateControl(txtName))
{
noErrors = false;
break;
}
// other code
}
If this is in a validation routine, I wouldn't even BOTHER with a WHILE() construct... In the past, I would typically test each specific validation routine that did just that... no looping involved such as
Function bool IsAllDataValid()
{
if ( ! (ValidateControl(txtName) )
return false;
if ( ! (ValidateControl(OtherField ))
return false;
etc...
return true;
}
Then you don't have to worry about where the mix is of include or bypass certain blocks of code... You could just have...
if IsAllDataValid()
{
Do Your Other Code
}
Related
Currently writing a file parser that runs through data files line by line and cleans the data. Performance is an important consideration for this application. The user assigns labels to the data columns to let the process know which column represents what kind of data - i.e. which is a surname field, which is an address field, which is a telephone number and so on.
I just finished writing a bunch of code that cleans phone numbers, and applied it like this:
public void CleanPhoneFields(FileRow row, List<Mapping> mappings)
{
// this will return empty if there's no field mapped with the "Telephone Number" tag
string phoneNumber = GetValueByAssignedLabel(row, mappings, "Telephone Number");
if(!string.IsNullOrEmpty(phoneNumber))
{
CleanTelephoneNumber(phoneNumber);
}
}
public void ProcessFile(FileContents fileContents)
{
foreach (FileRow row in fileContents.FileRows)
{
// does other cleaning functions too
CleanPhoneFields(row, fileContents.Mappings, fc);
}
}
Then I realised that by checking the phone field on a row by row basis was unnecessary - it was true for the first line in the file, it'd be true for all of them. So I might be better off doing this:
public void CleanPhoneFields(FileRow row, List<Mapping> mappings)
{
// this will return empty if there's no field mapped with the "Telephone Number" tag
string phoneNumber = GetValueByAssignedLabel(row, mappings, "Telephone Number");
CleanTelephoneNumber(phoneNumber);
}
public void ProcessFile(FileContents fileContents)
{
bool firstLine = true;
bool cleanPhoneNeeded = false;
foreach (FileRow row in fileContents.FileRows)
{
if(firstLine)
{
cleanPhoneNeeded = !string.IsNullOrEmpty(GetValueByAssignedLabel(row, fileContents.Mappings, "Telephone Number"));
firstLine = false;
}
if(cleanPhoneNeeded)
{
CleanPhoneFields(row, fileContents.Mappings, fc);
}
}
}
I still have to go and get the field value for each row, so all I'm "saving" in this case is getting rid of a call to string.IsNullOrEmpty on each row. On the flipside, the second code is (to my eye) slightly less readable, and has lost a little defensive coding.
Is getting rid of string.IsNullOrEmpty going to save me much in the way of processing cycles? Is it worthwhile for the small downsides of the second approach. Or is there a better way to approach this?
Use the Stopwatch class in the System.Diagnostics namespace and you can measure the time it takes your program to execute in milliseconds.
Try with and without the null and empty checker (Although ill doubt there is much of a measurable difference)
More info found here:
https://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch(v=vs.110).aspx
IMO the affect of the string.IsNullOrEmpty call is negligible.
The benefit of your second solution though is that it eliminates the whole CleanPhoneFields call, and more importantly, the GetValueByAssignedLabel call which seems to be the slowest part (except the actual Clean part which cannot be avoided when needed).
However, I would refactor the original procedure slightly different, keeping the tradeoff between readability and performance.
First, I would make the CleanPhoneFields method to return bool:
public bool CleanPhoneFields(FileRow row, List<Mapping> mappings)
{
// this will return empty if there's no field mapped with the "Telephone Number" tag
string phoneNumber = GetValueByAssignedLabel(row, mappings, "Telephone Number");
if(string.IsNullOrEmpty(phoneNumber)) return false;
CleanTelephoneNumber(phoneNumber);
return true;
}
Then the main method could be like this:
public void ProcessFile(FileContents fileContents)
{
bool cleanPhoneFields = true;
foreach (FileRow row in fileContents.FileRows)
{
if (cleanPhoneFields)
cleanPhoneFields = CleanPhoneFields(row, fileContents.Mappings, fc);
// Other stuff
}
}
string.IsNullOrEmpty has practically no cost (nothing you can be worried about anyway)
What you might wanna do on the other hand is declaring the "Telephone Number" as a private const field to prevent it's creation every time you call CleanPhoneFields method.
You can also use string.Intern to prevent that ...
In second solution, inside loop each time you check two conditions plus null condition check for first row, instead in first solution there is only one null condition check plus it's more cleaner. it seems first solution is better in theory.
As #Harry Young said use Stopwatch to measure performance and if you are using VS2015, in debug mode it measure performance.
I am trying break; out of frustration. Is there an event handler I need to know about in console?
You're only setting the value of capslock once, prior to entering the loop. bool is a value type, so you get a copy of the Console.CapsLock property, not a reference to it. Your variable is never going to change value after that first assignment. What you want is something like:
while(Console.CapsLock)
{
// inform user, perhaps remove the loop and just tell them once
}
Or
capslock = Console.CapsLock;
while(capslock)
{
Console.WriteLine("CapsLock on");
capslock = Console.CapsLock;
}
On a side note, writing a message as fast as possible in a loop is probably a bad idea since it's just going to fill up the screen before the user has a chance to do anythign about it.
Not to answer your original question but it appears the reason you are checking for caps lock is you want the username that is going to be typed in in all lowercase so you can do a users.Contains(username) or something similar below where you provided in the screenshot.
A better way to do it is use the contains overload that lets you set a comparer, then use a case insensitive string comparer to test.
if(users.contains(username, StringComparer.OrdinalIgnoreCase))
{
//username existed
}
else
{
//username did not exist
}
There are similar overloads for String.Equals that lets you ignore case too
//This would return true if "username = marietjie" and "testUsername = MARIETJIE"
if(username.Equals(testUsername, StringComparison.OrdinalIgnoreCase))
{
//username matched
}
else
{
//username did not match
}
The solution for this kind of problem!!
I was looking at a code sample in C#. There is ; without any statement before it. I thought it is typo. I tried to compile with ;. It compiled fine. What is the use of ; without any code statement?
I'm using VS 2010, C# and .Net 4.0
private void CheckSmcOverride(PatLiverSmc smc)
{
;
if (smc.SmcOverride && smc.Smc != null
&& smc.Smc.Value < LiverSmcConst.SMC_OVERRIDE_POINT)
{
smc.Smc = 10;
_logger.DebugFormat("CheckSmcOverride: Override SMC {0}", smc.Smc);
}
}
A semicolon in C# is simply to denote an end-of-a-statement. Empty statements, or just a ; by itself, are valid.
You could have the following on a line by itself inside any function in C# and it should will compile fine:
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
On the same topic, but semi-different from the question at hand, is an empty set of curly-brackets, { }. These denote a "code block", but are valid just about anywhere in your code. Again, you could have something like the following on a single line and it will still compile fine:
{ } { ;;;;;;;;;; } { }
In the end, the empty-statement and empty-code blocks all compile down to "nothing to see here folks, move along" and can, in most cases, be removed from the code without consequence.
As a c# developer I use the 'empty statement'
;
(a useful case as a comment requested)
when I have a multi line lambda and I want to examine the last line of evaluation i.e.
list.ForEach(x=>
{
x.result = x.Value * x.AnotherValue;
; // otherwise I can't ever see these as you can't break on the end brace of an anonymous function
})
as a way to break point inside some code after evaluation of the line before i.e.
void SomeFunct()
{
int a = someOtherFunct();
; //I want a breakpoint here but...
//there is some huge code segment that will get skipped before I can breakpoint
}
It's a statement that does nothing. Normally this would be pointless and could just be removed, but there are times where a statement is expected and you really want nothing to happen.
Sometimes you see this with loops that cause side effects and so need no body:
int count = 0;
while(isTheRightNumber(count++))
;
Personally I dislike such code examples and discourage the practice as they tend to be harder to understand than loops that have side effect free conditions. Using a set of empty braces is a bit clearer, as is including a relevant comment, such as:
int count = 0;
while(isTheRightNumber(count++))
{ } //empty by design
Another example is the pattern of using a for loop for an infinite loop:
for(;;)
{
//stuff
}
is essentially the same as:
while(true)
{
//stuff
}
It's an empty statement. I never used it, but it exists in many languages.
semicolon(;) indicated the end of a statement. so if you just add a semicolon without anything... it means it is empty statment
An empty statement is sometimes used when a statement expects a block but you don't want it to do anything.
For example:
for(i=0; array[i]!=null; i++)
;
or for nested if then elses without braces:
// don't really do this kids
if(cond1)
if(cond2)
doit();
else
;
else
dont();
Sometimes used for 'if' clarity:
if(somecomplicatedconditionisnotfalseinverted()) // <-- this is already complicated enough, let's not ! that.
; // do nothing
else {
ohnoes();
}
But in your example, it does absolutely nothing when built for release and just adds a nop when built for debug, so you can drop a breakpoint on it.
How can I go about doing this so if the "if" statement is true, to skip the code below the foreach loop and to go on with the rest of the program
void()
{
foreach()
{
if()
{
}
}
//code I want to skip if "if" statement is true
}
There's no way to directly do what you want (without "goto" labels -- perish the thought!), but you can use the "break" keyword, and set a variable you can refer to later.
void()
{
var testWasTrue = false;
foreach()
{
if()
{
testWasTrue = true;
break; // break out of the "foreach"
}
}
if( !testWasTrue ) {
//code I want to skip if "if" statement is true
}
}
I know this was already answered, but I figured I'd throw in my 2 cents since nobody considered abstracting the check to a separate method:
void()
{
if (ShouldDoStuff(myCollection))
DoStuff(myCollection);
else
DoOtherStuff(myCollection);
}
private bool ShouldDoStuff(collection)
{
foreach()
{
if ()
return true;
}
return false;
}
This provides a much cleaner code at the higher level for dealing with your algorithms and removes all the clutter discussed about. It cleanly separates the tasks in void() of checking and performing the actions and readers instantly know exactly what the program flow is without having to discern what they're doing with a boolean or break logic lurking about. No single method has more than 1 responsibility or task.
Yeah, it's possible the poster wants to do other work in their foreach, but that's an entirely different discussion and not what was described in their question. If you simply want to check if the given collection (or object) satisfies a certain condition, that check can be moved to a separate method. Even leaves the door open for automated unit tests for all three components.
Even if DoStuff and DoOtherStuff are not abstracted to their own methods, it provides nicer readability and logical flow.
void()
{
bool process = true;
foreach()
{
if()
{
process = false;
break;
}
}
if (process)
{
//code I want to skip if "if" statement is true
}
}
As was mentioned in my comment you may do this through extra bool variable.
void()
{
bool positiveResult; // by default it gets false value
foreach()
{
if()
{
positiveResult = true;
// you may use "break" to skip the loop
break;
}
}
if( !positiveResult )
{
//code I want to skip if "if" statement is true
}
}
The 'break' keyword will break out of the loop.
foreach (someClass a in someArray)
{
if(a.someProperty) // bool property
{
//Stuff to do if that condition is true
doSomethingElse();
//Calling the break keyword will stop the loop and jump immediately outside of it
break;
}
//Other code to run for each iteration of the loop
}
//Here is where execution will pick up either after break is called or after the loop finishes
Only way I know how is a bool flag.
void()
{
bool x = false;
foreach()
{
if()
{
x = true;
break;
}
}
if(!x)
{
//Code to skip if "if" statement is true.
}
}
Not super elegant, but easy.
Edit: beat by 12 secs :)
void()
{
bool skip = false;
foreach()
{
if()
{
skip = true;
}
}
if(!skip)
{
//code I want to skip if "if" statement is true
}
}
If the collection you are iterating through contains The IEnumerable Interface, You could use Any() with a Lambda!
int[] myArray = { 1, 2, 3 };
if( myArray.Any((a) => a == 1) )
{
return;
}
It is read: if my array contains any value a where a is equal to 1, then return out of this function.
Plus if you want to make it harder to read, you can omit the curly braces/brackets.
if( myArray.Any((a) => a == 1) )
return;
This is my recursive function :
public bool controllaSelezioneSottopagina(KPage k_oPaginaAttuale, KPage k_oPaginaSuperiore)
{
foreach (KPage k_oSottoPagina in k_oPaginaSuperiore.SottoPagine)
{
if (k_oSottoPagina.ID == k_oPaginaAttuale.ID)
{
return true;
}
else
{
if (k_oSottoPagina.SottoPagine.Count != 0)
{
controllaSelezioneSottopagina(k_oPaginaAttuale, k_oSottoPagina);
}
}
}
return false;
}
I aspect, from where I call it, to get ALWAYS false (the return false at the end of the function, will be the last result that will be returned, EVER).
In fact, sometimes it returns true.
How it is possible? Tried debugging... but I can't find out the mistake...
You call the function once, then it loops, and either returns true or calls itself recussively. It will only return false if it loops through all elements and the condition (k_oSottoPagina.ID == k_oPaginaAttuale.ID) is never met.
Now assume that this condition is actually met in the first level (there was no recursion made yet or all recursive call return).
You call the function once, it loops and for example on the first test this condition is true. Then you will see a return value 'true'
I think this could happen only in first iteration. I mean that only first comparison may result in returning true. Recursive call would never happen then.
Are you saying this code block will never be true in the first call to the function (the first time through the loop)?
k_oSottoPagina.ID == k_oPaginaAttuale.ID
Since you don't return the result of the recursive call, your function either blows the stack, returns true through the first loop at some point, or finishes the loop and returns false.
another alternative to not printing incorrect false in the cases where it does go in the loop is
public bool controllaSelezioneSottopagina(KPage k_oPaginaAttuale, KPage k_oPaginaSuperiore)
{
foreach (KPage k_oSottoPagina in k_oPaginaSuperiore.SottoPagine)
{
if (k_oSottoPagina.ID == k_oPaginaAttuale.ID)
{
return true;
}
else
{
if (k_oSottoPagina.SottoPagine.Count != 0)
{
if(controllaSelezioneSottopagina(k_oPaginaAttuale, k_oSottoPagina))
{
return true;
}
}
}
}
return false;
}