I have code like this:
public void Method()
{
if(something)
{
// Some code
if(something2)
{
// Now I should break from ifs and go to the code outside ifs
}
return;
}
// The code I want to go if the second if is true
}
Is there a possibility to go to that code after ifs without using any go to statement or extracting rest of the code to the other method?
Yes, I know Else ;)
But this code is farly long and should be run IF the first IF is false and when the first IF is true and the second is false.
So extracting a method I think is the best idea.
To answer your question:
public void Method()
{
do
{
if (something)
{
// some code
if (something2)
{
break;
}
return;
}
break;
}
while( false );
// The code I want to go if the second `if` is true
}
You can use a goto to drop past some code. In the example, if thing1 is true then the check for things2 is bypassed.
if (something) {
do_stuff();
if (thing1) {
do_thing1();
goto SkipToEnd;
}
if (thing2) {
do_thing2();
}
SkipToEnd:
do_thing3();
}
This is a variation of something I learned several years back. Apparently, this is popular with C++ developers.
First off, I think I know why you want to break out of IF blocks. For me, I don't like a bunch of nested blocks because 1) it makes the code look messy and 2) it can be a PITA to maintain if you have to move logic around.
Consider a do/while loop instead:
public void Method()
{
bool something = true, something2 = false;
do
{
if (!something)
break;
if (something2)
break;
} while (false);
}
The do/while loop is guaranteed to run only once just like an IF block thanks to the hardcoded false condition. When you want to exit early, just break.
public void Method()
{
if(something)
{
// Some code
if(something2)
{
// Now I should break from ifs and go to the code outside ifs
goto done;
}
return;
}
// The code I want to go if the second if is true
done: // etc.
}
Same question
Long answer
Another way starting from C# 7.0 would be using local functions. You could name the local function with a meaningful name, and call it directly before declaring it (for clarity). Here is your example rewritten:
public void Method()
{
// Some code here
bool something = true, something2 = true;
DoSomething();
void DoSomething()
{
if (something)
{
// Some code
if (something2)
{
// Now I should break from ifs and go to the code outside ifs
return;
}
return;
}
}
// The code I want to go if the second if is true
// More code here
}
public void Method()
{
if(something)
{
// Some code
if(!something2)
{
return;
}
}
// The code I want to go if the second if is true
}
In this case, insert a single else:
public void Method()
{
if(something)
{
// Some code
if(something2)
{
// Now I should break from ifs and go to the code outside ifs
}
else
return;
}
// The code I want to go if the second if is true
}
Generally: There is no break in an if/else sequence, simply arrange your code correctly in if / if else / else clauses.
public void Method()
{
if(something)
{
// Some code
if(something2)
{
// The code I want to go if the second if is true
}
return;
}
}
You can return only if !something2 or use else return:
public void Method()
{
if(something)
{
//some code
if(something2)
{
//now I should break from ifs and go to the code outside ifs
}
if(!something2) // or else
return;
}
// The code I want to go if the second if is true
}
In your code example, you should simply run the code after the ifs inside the second if instead (or set a flag like someone else mentioned, depending on the context). Use method calls to improve readability and reduce nesting.
As for actually escaping ifs, I think there is a way that conforms much more to C# standards than the answers I've seen here. Simply extract the contents of the if statement to a separate method. This also increases readability. So:
public void Method()
{
if(something)
{
//some code
if (somethingelse)
{
//break if
}
//some other code running if the above if didn't trigger
}
}
This can be accomplished as such:
public void Method()
{
if(something)
{
DoSomething();
}
}
public void DoSomething()
{
//some code
if (somethingelse)
{
return;
}
//some other code running if the above if didn't trigger
}
You can also use a lambda
if (new Func<bool>(() =>
{
if (something1)
{
// Some code that calculates "something2"
if (something2)
{
// Now I should break from ifs and go to the code outside ifs
return true;
}
}
return false;
})())
{
// The code I want to go if the second if is true
}
P.S. I think I know why people would want this. "Run stuff if all conditions are true, otherwise run other stuff". And the conditions are too complicated to put into one if or they depend one on another.
Try adding a control variable:
public void Method()
{
bool doSomethingElse = true;
if(something)
{
// Some code
if(!something2)
{
doSomethingElse = false;
}
}
if(doSomethingElse)
{
// The code I want to go if the second if is true
}
}
Another variant that may be really useful in more complicated cases:
try {
if (something)
{
// Some code
if (something2)
{
throw new Exception("Weird-01.");
// Now you will go to the catch statement
}
if (something3)
{
throw new Exception("Weird-02.");
// Now you will go to the catch statement
}
// Some code
return;
}
}
catch (Exception ex)
{
Console.WriteLine(ex); // You will get your Weird-01 or Weird-02 here
}
// The code I want to go if the second or third if is true
if (contREsponse == "yes")
{
cont = true;
}
else if (contREsponse == "no")
{
Console.WriteLine("Come back, when you change your mind.");
//exit environment:
Environment.Exit(0);
}
Related
I have a while loop with a stopper:
public Myloop()
{
bool execute == true;
While (execute == true)
{
// do some stuff
if (condidtion)
{
execute == false;
}
}
}
and I'm calling in from another function after it stops:
Myloop.execute = true;
Will this be enough to restart the loop? if not, how can I restart it from another function easy way?
No, Once a while loop is done it wont start again until you run the Myloop() function again:
public void RunLoopTwice(){
MyLoop();
MyLoop();
}
public void Myloop()
{
bool execute = true;
while (execute == true)
{
// do some stuff
if (condition)
{
execute = false;
}
}
}
Also normally code is executed in a synchronous order, so only 1 piece of code is executed at the time. with async/await, Task or Thread you can make multiple pieces of code run at once. If you are using any of this, you need to make sure you properly lock pieces of code to not get any race conditions.
You are confusing == and = operators, == is for comparison while = is for assignment. Read about C# Operators.
public void Myloop()
{
bool execute = true;
while (execute == true)
{
// do some stuff
if (condition)
{
execute = false;
}
}
}
Simpler way to do this is using break since you are not returning the value of execute field. Once the condition is met, while loop will terminate.
while (true)
{
// do some stuff
if (condition) break;
}
And you call the method using Myloop(); not Myloop.execute = true;.
You can do with two flags but this code will be run on the different thread because this code will go in the infinite loop.
For Ex.
public bool doLoop = true;
public bool doProcess = true;
public void MyLoop()
{
while(doLoop)
{
while(doProcess)
{
// do some stuff
if (condition)
{
doProcess = false;
}
}
}
}
After your need is completed than make doLoop false
I have a function Parent() and a boolean Class Property Watch with default value true.
This fn Parent() is calling several Child functions.
Lets assume during execution of this function or any of the child functions Watch Changes its value to false , i want the execution to stop and exit the Parent function.
Parent is returning void.
This is a single threaded execution , no async and Task constructs being used
I think the easiest thing to do is to use exceptions for this:
public class TestClass
{
public void ParentMethod()
{
try
{
ChildMethod1();
ChildMethod2();
}
catch (InvalidStateException ise)
{
return;
}
}
public void ChildMethod1()
{
//do stuff, and then if the "watch" is set to true:
throw new InvalidStateException();
}
public void ChildMethod2()
{
//do stuff, and then if the "watch" is set to true:
throw new InvalidStateException();
}
}
public class InvalidStateException : Exception { }
Here I've defined a new exception InvalidStateException that the ChildMethodX can raise when it wants the parent method to stop execution. In the parent method you try/catch all the child calls, and when one throws, it stops the execution and skips into the catch.
Note: Exceptions occur because something exceptional happens. If you expect that this would be a normal flow of logic, then I would implore you to try something that avoids exceptions. Exceptions are expensive performance wise. For example, without using exceptions you could do something like:
public class TestClass
{
public bool Watch { get; set; }
public void ParentMethod()
{
Func<bool> c1Call = () => { Child1Method(); return Watch; };
Func<bool> c2Call = () => { ChildMethod2(); return Watch; };
if (c1Call())
return;
if (c2Call())
return;
}
public void Child1Method()
{
//Do something, then this happens:
Watch = true;
}
public void ChildMethod2()
{
//Do something, then maybe this happens:
Watch = true;
}
}
Where you could modify the Func<> delegates to take any number of arguments. There are a dozen ways to skin this cat, but almost all of them involve checking the flag after calling the function to determine if you want to exit or not. If you functions return void, consider changing them to return bool so you could do something like:
if (ChildMethod1()) return;
Which is pretty concise. Otherwise you can use strange combinations of lambda's and delegates, but when you get down to it you have to ask yourself, is avoiding typing a couple extra "if" statements worth the loss in code maintainability?
Here is a demo mock up how you can construct that.
It demonstrates a workflow where Child2 sets the variable to false and exits after that and therefore never executed Child3.
However I would suggest to have the child functions return a bool instead. Seems not a good design what you are suggesting for a single threaded application.
public class Test
{
public bool Watch { get; set; }
public Test()
{
this.Watch = true;
}
public void Parent()
{
this.Child1();
if(this.Watch == false)
{
return;
}
this.Child2();
if(this.Watch == false)
{
return;
}
this.Child3();
if(this.Watch == false)
{
return;
}
}
public void Child1()
{
//Do stuff
}
public void Child2()
{
this.Watch = false;
}
public void Child3()
{
//Do stuff
}
}
You can either execute each Child function in a different thread and have a loop in the Parent function monitor the Watch value or you can check the Watch value after each Child call. Without a code example or more information, it is difficult to answer.
fn Parent()
{
childfn();
if( !Watch )
return;
}
Though might be better to have child functions return bool and check that rather than use class property.
i assume this is yr code structure.. if my assumption is wrong please correct me
I also have a question - all the child functions have same signature ? if so I'll suggest approach based on delegates. Otherwise here is a simple example
bool Watch { get; set; }
// Parent is control center, calling one child after another
void Parent()
{
ChildOne(1);
if (Watch == false)
return;
ChildTwo(1,3);
if (Watch == false)
return;
}
/// signature type 1
void ChildOne(int a)
{
}
/// signature type 2
void ChildTwo(int a, int b)
{
Watch = false;
}
EDIT 1
here is the approach if all functions have same signature
class ChildFuntionExecutor
{
public Func<int,int> ChildFuntion;
public int Operand1;
public void Evaluate()
{
ChildFuntion(Operand1);
}
}
bool Watch { get; set; }
// Parent is control center, calling one child after another
void Parent()
{
// register all child functions
List<ChildFuntionExecutor> childFuntionQueue = new List<ChildFuntionExecutor>();
childFuntionQueue.Add(new ChildFuntionExecutor { Operand1 = 10, ChildFuntion = this.ChildOne });
childFuntionQueue.Add(new ChildFuntionExecutor { Operand1 = 10, ChildFuntion = this.ChildOne });
foreach (var item in childFuntionQueue)
{
item.Evaluate();
if (Watch == false)
return;
}
}
/// signature type 1
int ChildOne(int a)
{
return a * 10;
}
/// signature type 1
int ChildTwo(int a)
{
Watch = false;
return a * 10;
}
I have a Validation method and a validation counter, I fire an event when the count of errors is equal to a number. How do I terminate the validation process? Maybe I should use Observer pattern?
class ValidationClass
{
private int errorsCount;
private delegate void CompleteHandler();
private event CompleteHandler ValidationComplete;
public int ErrorsCount
{
set
{
errorsCount = value;
if (errorsCount == 20)
{
ValidationComplete();
}
}
get { return errorsCount; }
}
public void ValidationClass()//constructor
{
ValidationComplete += ExcelHelpers_Complete;
}
void Validation_Complete() //
{
//terminate Validate() and return false; how?
}
public bool Validate()
{
for(...){
ErrorsCount++;
for(...){
....
ErrorsCount++;
}
....
//others conditions that increment ErrorsCount
}
}
Have your subscriber check the number of error count and do nothing if its past your maximum range. If your subscriber does not have access to the publisher object than pass the count inside the event itself. Your subscriber could also unsubscribe once this condition has been met.
Move the following code into your Validate() method:
if (errorsCount == 20)
{
ValidationComplete();
}
Now use break statement to abort your loop when the condition is true and raise ValidationComplete() event thereafter.
Your property will look like this:
public int ErrorsCount
{
set { errorsCount = value; }
get { return errorsCount; }
}
and Validate() method would look like this:
public bool Validate()
{
for(...){
ErrorsCount++;
if(Check20()) break;
for(...){
....
ErrorsCount++;
if(Check20()) break;
}
if(Check20()) break;
....
//others conditions that increment ErrorsCount
if(Check20()) break;
}
}
private bool Check20()
{
if(ErrorsCount==20)
{
ValidationComplete();
return true;
}
return false;
}
If you dislike all that repetition, you can create a small function for it too.
Throw a custom exception inside the ErrorsCount setter (or better yet, create an IncrementErrorCount() method) when ErrorCount reaches 20. Then catch it and return.
try {
...
IncrementErrorCount();
...
} catch(TooManyErrorsException) {
return;
}
It is a bit of an anti-pattern of using exceptions for control throw, but if this is an exceptional circumstance, and if this is a client app and this doesn't happen in a loop, it is ok.
Another approach: it's hard to tell from your abbreviated code, but if all your checks are in loops, you may also be able to put the check into the for loop condition:
for(...; oldCondition && ErrorCount < 20; ...) {
}
ValidationComplete();
public class Example {
private boolean jobInProgress = false;
public void job() {
lock(this) {
if (jobInProgress) {
return;
}
jobInProgress = true;
}
// Code to execute job goes here
// ...
}
void jobCompleted() {
lock(this) {
jobInProgress = false;
}
}
}
I got this piece of code from Wikipedia and i have one thing i am not sure of.
Why jobInProgress = true; is not set inside the locked block just after the return statement? To be more explicit i will try to give a scenario:
One thread gets the lock while others are waiting
It releases the lock but before executing jobInProgress = true;, one of the waiting threads gets the lock and tests the condition which is still false.
Is this a feasible scenario or am i not getting the flow of execution right?
You are confusing yourself:
lock(this) {
if (jobInProgress) {
return;
} // <= closing brace of if
// INSIDE LOCK, OUTSIDE IF
jobInProgress = true;
} // <= closing brace of lock
I'll note that on the wiki:
public void job() {
synchronized(this) {
if (jobInProgress) {
return;
}
// INSIDE LOCK, OUTSIDE IF
jobInProgress = true;
}
// Code to execute job goes here
// ...
}
it is exactly the same!
I have a boolean function which is used in the decision-making of many other functions. And every time, the user is either given a message box or allowed to proceed, depending on the return value of that function. So my pseudo-code might look like this:
private bool IsConsented()
{
//some business logic
}
private void NotReal()
{
if (IsConsented())
{
//call function A
}
else
{
MessageBox.Show("Need consent first.");
}
}
private void NotReal2()
{
if (IsConsented())
{
//call function B
}
else
{
MessageBox.Show("Need consent first.");
}
}
I am looking for a simpler way to do this, rather than hard-coding that if-else logic into every single function of mine. I'd like to be able to have a function like:
private void CheckConsent(function FunctionPointer)
{
if (IsConsented())
{
//call the function
FunctionPointer();
}
else
{
MessageBox.Show("Need consent first.");
}
}
So that I can just pass a pointer to a function. I have a real suspicion that this has to do with delegates, but I don't know the syntax, and I don't understand how to pass parameters around using delegates.
You need to declare the delegate (or use a built-in one, such as Action):
private void CheckConsent(Action action)
{
if (IsConsented())
{
action();
}
else
{
MessageBox.Show("Need consent first.");
}
}
You could then do:
private void NotReal()
{
this.CheckConsent( () =>
{
// Do "NotReal" work here...
});
}
Reed Copsey way of doing is clean one. It uses the Action delegate already defined along with lambda expression. But if you are not comfortable with that here is the old way of doing .
private delegate void realDelegate();
realDelegate d = new realDelegate(NotReal);
You can now call
private void CheckConsent(realDelegate d)
{
if(d !=null)
d();
}