How to make logical behavior behave like a “latch”?

First I had the following code:

Boolean successCheckPoint = false; Boolean failureCheckPoint = false; Boolean timeFound = false; foreach (var row in auditRows) { timeFound = row.Text.Contains(sCurrentTime) || row.Text.Contains(sLenientTime) || row.Text.Contains(sLenientTime2) ? true : false; if (timeFound) { successCheckPoint = row.Text.Contains("Web User Login Success") && !successCheckPoint ? true : false; failureCheckPoint = row.Text.Contains("Web User Login Failure") && !failureCheckPoint ? true : false; } } 

But I found that in subsequent foreach iterations, even if successCheckPoint or failCheckPoint booleans were set to true, they would eventually get false due to the way I set the assignment.


Problem example

First iteration

  • timeFound is true
  • successCheckPoint - false
  • row.Text contains the text I want
  • successCheckPoint is really wrong
  • successCheckPoint set to true

Second iteration

  • timeFound is true
  • successCheckPoint true
  • row.Text does not contain the text I want
  • successCheckPoint is not false
  • successCheckPoint set to false

So, to fix the problem, I changed the code to this:

  Boolean successCheckPoint = false; Boolean failureCheckPoint = false; Boolean timeFound = false; foreach (var row in auditRows) { timeFound = row.Text.Contains(sCurrentTime) || row.Text.Contains(sLenientTime) || row.Text.Contains(sLenientTime2) ? true : false; if (timeFound) { if (!successCheckPoint) { successCheckPoint = row.Text.Contains("Web User Login Success") ? true : false; } if (!failureCheckPoint) { failureCheckPoint = row.Text.Contains("Web User Login Failure") ? true : false; } } } 

This does what I want, but there seems to be a better way to do this behavior. Is there a way to configure things so that after the boolean value is set to true, it will not be changed to false for future iterations?


Correct behavior

First iteration

  • timeFound is true
  • successCheckPoint - false
  • row.Text contains the text I want
  • successCheckPoint is really wrong
  • successCheckPoint set to true

Second iteration

  • timeFound is true
  • successCheckPoint is true, so re-evaluate the skips

Sorry if this is still confusing. I can explain a little more if necessary.


Edit: Now that I think about it, I really don't need to? true: false "for this code.

New code:

  Boolean successCheckPoint = false; Boolean failureCheckPoint = false; Boolean timeFound = false; foreach (var row in auditRows) { timeFound = row.Text.Contains(sCurrentTime) || row.Text.Contains(sLenientTime) || row.Text.Contains(sLenientTime2); if (timeFound) { if (!successCheckPoint) { successCheckPoint = row.Text.Contains("Web User Login Success"); } if (!failureCheckPoint) { failureCheckPoint = row.Text.Contains("Web User Login Failure"); } } } 

Thanks for helping everyone! Here is the version of the code I settled on:

  Boolean successCheckPoint = false; Boolean failureCheckPoint = false; Boolean timeFound = false; foreach (var row in auditRows) { if (row.Text.Contains(sCurrentTime) || row.Text.Contains(sLenientTime) || row.Text.Contains(sLenientTime2)) { successCheckPoint |= row.Text.Contains("Web User Login Success"); failureCheckPoint |= row.Text.Contains("Web User Login Failure"); } if (successCheckPoint && failureCheckPoint) { break; } } 
+4
source share
3 answers

You can use the OR |= operator:

 bool successCheckPoint = false; bool failureCheckPoint = false; foreach (var row in auditRows) { if (row.Text.Contains(sCurrentTime) || row.Text.Contains(sLenientTime) || row.Text.Contains(sLenientTime2)) { successCheckPoint |= row.Text.Contains("Web User Login Success"); failureCheckPoint |= row.Text.Contains("Web User Login Failure"); } } 

a |= b; shortened for a = a | b; a = a | b; . Therefore, if a already true, it remains true. If a false and b is true, then a becomes true. Otherwise, a remains false.

+8
source

Just use the OR operator, as in:

 bool failed = false; failed |= CheckOne(); failed |= CheckTwo(); 
+6
source

I do not like the other answers, as they complicate this code. I feel linq will help make your code more readable:

 var rows = auditRows.Where(TimeIsFound); var successCheckPoint = rows.Any(RowContainsSuccess); var failureCheckPoint = rows.Any(RowContainsFailure); ...elsewhere... static bool TimeIsFound(SomeType row) { return row.Text.Contains(sCurrentTime) || row.Text.Contains(sLenientTime) || row.Text.Contains(sLenientTime2); } static bool RowContainsSuccess(SomeType row) { return row.Text.Contains("Web User Login Success"); } static bool RowContainsFailure(SomeType row) { return row.Text.Contains("Web User Login Failure"); } 

I feel this will make the code easier to execute, it will almost become a paragraph:

Get strings where certain times will be found. successCheckPoint true if any of the lines contains a success message. failureCheckPoint true if any of the lines contains an error message.

Ease of reading helps simplify debugging later. In addition, it divides functionality into pieces the size of a slice.

Do not worry about cycling several times. If you loop over 100 elements and perform 3 actions, it takes about the same time as a loop 3 times for 100 elements and each time performs 1 action ( 1 * 100 * 3 == 3 * 100 * 1 , go figure)

+1
source

All Articles