Is it possible to exit a scope in C# like it's possible to break out of a loop for example?
private void a()
{
// do stuff here
{
// do more stuff here
break;? //<-- jump out of this scope here!! break won't work
// this further code should not be executed
}
// do stuff here
}
You can use break to break out of a loop or switch, but you cannot break out of a simple block like this.
There are ways to achieve this, for example using goto or artificial while loop, but it definitely sounds like a code smell.
You can achieve what you want using simple condition which will make your intention much more clear.
Instead of:
DoSomething();
if (a == 1) // conditional break
{
break;
}
DoSomethingElse();
break; // unconditional break (why though)
UnreachableCode(); // will generate compiler warning, by the way
You can do:
DoSomething();
if (a != 1) // simple condition
{
DoSomethingElse();
if (false) // why though
{
UnreachableCode(); // will generate compiler warning, by the way
}
}
Alternatively, you can extract this part to a separate named method and short-circuit using return statements. Sometimes, it really makes code more readable, especially when you have a return value:
private void a()
{
// do stuff here
MeaningfulNameToDescribeWhatYouDo();
// do stuff here
}
private void MeaningfulNameToDescribeWhatYouDo()
{
// do more stuff here
if (condition)
{
return; //<-- jump out of this scope here!!
}
// this further code should not be executed
}
Yes, it is possible to use goto statements but I strongly suggest you don't use them until you gain more experience with the language. I never use goto and I don't know of any programmers who do, because it can make your code a giant spaghetti mess and there are generally better alternatives.
There's ways to use them responsibly, but from your question it sounds like you're not sure how to properly use if/else/while etc. statements. Instead it's better to use proper flow controls.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto
Related
I have a program that is completely functional, and I am now refactoring it. I am just in the process of learning c# so the original code was pretty terrible despite the fact that it ran just fine. One of the requirements of the program is that the user be able to return to the main menu at any point. I accomplished this as follows:
static bool bouncer = false
static void Exit(string input)
{
if (input == "\t")
{
bouncer = true
}
}
static string Prompt(string msg)
{
// takes input and passes it to Exit() then returns the input
}
static string FunctionA()
{
while(true)
{
if (bouncer == true)
{
break;
}
Prompt("whatever")
if (bouncer == true)
{
break;
}
Prompt("whatever")
if (bouncer == true)
{
break;
}
// return some stuff
}
}
static void Main()
{
bouncer = false
// writes the menu to console and handles UI
// FunctionA
{
The variable bouncer gets set to true if the user enters the "tab" character at any input point. The proliferation of break statement conditionals provides the structure that actually breaks out back to Main(). This is obviously not a very good solution and it makes the code hard to read.
Other attempts that I considered to accomplish the same task are:
Goto statement that jumps straight back to Main(). I scrapped this because goto has a very limited scope in c# and I don't think there is any good way to make it workable in this situation.
Calling Main() directly from Exit(). This is probably a bad idea, and I can't do it anyway because apparently Main() is "protected" in some way.
Using an event to react to TAB or ESC being pressed. It's unclear to me how I could use an event to do this since I still wouldn't be able to break right out of the event. My understanding is that the break statement has to actually be contained in the loop that needs to be broken as opposed to being written into a different function that is called from within the loop.
Any suggestions are greatly appreciated. I'm hoping there's something to be done with event handling or that I've overlooked something more simple. Thanks!
As a matter of coding style, the way it is works, but is seen as ugly. Unfortunately, if you need to break out immediately between sections of work, there is not a lot of ways around that.
You can change your current format of using breaks to using "if( bContinue ) { /* do next section of work */ }" control style. It changes the code from break out of the while loop to this:
static string FunctionA()
{
bool bContinue = true;
while( true == bContinue )
{
// Do initital work.
//
// Initial work can set bContinue to false if any error condition
// occurs.
if( true == bContinue )
{
// Do more work.
int returnCheck = MakeACall(); // Presume MakeACall returns negative interger values for error, 0 or positive values for success or success with condition/extra information.
if( 0 < returnCheck )
{
bContinue = false;
}
}
if( true == bContinue )
{
Prompt("whatever")
// Do more work.
bContinue = MakeASecondCall(); // Presume that MakeASecondCall returns true for success, false for error/failure
}
if( true == bContinue )
{
Prompt("whatever")
// Do more work.
// If error encountered, set bContinue to false.
}
if( true == bContinue )
{
Prompt("whatever else")
// Do more work.
// If error encountered, set bContinue to false.
}
// Done with loop, so drop out.
bContinue = false;
// return some stuff
}
}
Looking at your pseudo code, it reads like you only do a single pass through your work loop. If so, you can switch to a Do-While(false) format, and use the break to just drop to the bottom. Or, if you are only doing a single pass through your FunctionA, just do away with the While or Do-While control structure, and just use the if(true==bContinue){ /* Do more work */ }. It is not the cleanest of code, but when you perform long periods of serial work, you end up with such structures if you are not going to use a while or do-while for controlling the flow.
The disadvantage to using the if(bContinue){} style is that when an error condition occurs during the early stages of the process, the code does not exit out as quickly from the function as a break out of the while() or do-while() structure if the error occurs near the top of the work, as there will be the series of if statements that the code will test and then skip over. But it is readable, and if you use a descriptive name for your control variable (ie, nContinue or bContinue or workLoopControl) it should be fairly obvious that it is the master control flag for the function's work flow to whoever works or reviews the code after you.
Instead of an infinite loop and break statements, try using a conditional flag instead.
static void FunctionA()
{
bool done = false;
string response = string.Empty;
while (!done)
{
response = Prompt("whatever");
if(response == '\t')
{
done = true;
}
}
}
As a side note, I'm not sure why you have 'string' as the return type of several methods (e.g., 'FunctionA') when you aren't using the return value. That's why the code I gave above has it as 'void'.
i have the following 3 examples which does the same thing
//case1 do it if the condition is valid
private void SetMultiplePropertyValues()
{
if (Keyboard.GetKeyStates(Key.CapsLock) == KeyStates.Toggled)
{
//do somthing
}
}
//case 2 return if the condition is not valid
private void SetMultiplePropertyValues()
{
if (Keyboard.GetKeyStates(Key.CapsLock) != KeyStates.Toggled) return;
//do somthing
}
//case 3 checking the condition in the calling scope
if (Keyboard.GetKeyStates(Key.CapsLock)== KeyStates.Toggled)
SetMultiplePropertyValues())
private void SetMultiplePropertyValues()
{
//do somthing
}
which one would you go with and why
They do not do the same thing because in the first two cases the name of the method is a lie; the method name should be SetValuesIfTheKeyStateIsToggled or TryToSetValues or some such thing. Don't say you're going to do a thing and then not do it. More generally: separate your concerns. I would choose a fourth option:
public void TryToFrob()
{
if (CanFrob()) DoFrob();
}
private bool CanFrob()
{
return Keyboard.GetKeyStates(Key.CapsLock) == KeyStates.Toggled;
}
private void DoFrob()
{
// frob!
}
Notice what is public and what is private.
This is a silly looking example because each one is so simple, but one can easily imagine a situation in which these methods are complex. Keep your policies and your mechanisms logically separated. The mechanism is "is the keyboard in a particular state?" The policy is "I have some conditions under which I can frob; we must never frob unless those conditions are met".
First of all, as we can see at code comments, they don't do the same thing. So I think that you're talking about code architecture rather than functionality.
Second, here in SO isn't about giving opinions, but I'll try say to you concrete things about these differences.
1- Common if approach
if (true == false)
{
return true;
}
vs.
2 - Single line if approach
if (true == false) return true;
Most of code convetions says to use the option 1, because they're easier to read and understant code, and avoid some mistakes. We need to also understand that convetions are not rules! so they're just convetions, but really try to avoid option 2 in most of the cases.
One more thing, some code convetions also says that's ok using option 2 when you need something very simple, like this given example which is really easy to read and understand. But take this like an exception from the 'rules'.
I'm using a switch as a state manager for my XNA game. The switch is a part of main update method, so it's run every frame. Sometimes I need to set a timer value and it should only be set once per method call. There are multiple methods that set the timer per case, so it can't use the current and previous state numbers to check if it's ok to overwrite previous time.
case "state 34": {
SetTime(theTime); // should run only once
// other things
if (TheTimeisRight(time)) // runs every call
{
SetTime(theTime); // should run only once
if (TheTimeisRight(time))
{ /* some methods */ }
}
break; }
How can I make this work, or is there a better way to do this without going outside the switch? (changing SetTime method is ok, but I wouldn't like to clutter up the switch with additional code)
Another method: Introduce a wrapper around the method you want to call:
public sealed class RunOnceAction
{
private readonly Action F;
private bool hasRun;
public RunOnceAction(Action f)
{
F = f;
}
public void run()
{
if (hasRun) return;
F();
hasRun = true;
}
}
Then create var setTimeOnce = new RunOnceAction(() => SetTime(theTime)); before the switch statement, and call there as setTimeOnce.run(). Adjust for parameters/return values as necessary.
If you don't want to mess with boolean variables ala hasSetTimeAlready, you can always introduce another state that calls the method, then proceeds to the original state.
Put the call outside the loop.
You might need a separate conditional statement to determine whether it should run at all, but that's got to be infinitely better than trying to use flags and/or various other smelly-code approaches to control repetitions of the call.
Edit:
here is what I mean by putting it in one place outside of the switch:
if (someCondition && someOtherCondition && yetAnotherCondition)
setTime(theTime); // just one call, in one place, gets executed once
switch(someValue)
{
case "state 34": {
//SetTime(theTime); // no longer necessary
// other things
if (TheTimeisRight(time)) // runs every call
{
//SetTime(theTime); // no longer necessary
if (TheTimeisRight(time))
{ /* some methods */ }
}
break;
...etc...
}
A word of advice: use an enumeration for your switch value rather than a string.
To be brutally honest, this is about as much as anyone can realistically help you with this without seeing a more complete code sample (I think the sample you gave us is somewhat contrived and not quite accurate to what you have?). Chances are that the best way to get round this problem is to deconstruct the switch statement and start again because either maintaining a state machine is not the best way to handle this situation or you need to introduce some other states.
I have resorted to using HashSet<int> to check if the current SetTime(time, num) method has not been called before with if (!hashSet.Contains(num)).
void SetTime(int time, int num)
{
if (!hashSet.Contains(num))
{
theTime = time;
hashSet.Add(num);
}
}
Sure doesn't look too cool, but works and it doesn't damage method call too much (visually), so the switch's readability is saved.
I usually fall into a situation where goto seems to be the best option to my mind. But I have read several times not to use it, and there is always an alternative. Now, I am trying something like this:-
try{
//Something that requires internet connectivity;
}
catch{
//Show a message-Internet connectivity lost,and go back to try
//-->FYI--Ignore "show message", because I am just appending this text to a
// textbox. So there won't be a problem of multiple ShowMessage Boxes.
}
Now, the best option seems to me is to use goto in catch statement, but I am trying to avoid it. try is the first statement in a function, and if I recall that function, I am piling up stacks, so thats not a better option as well. What alternative can I take?
Use a while loop with a flag
var tryAgain = true;
while (tryAgain)
{
try
{
...
tryAgain = false;
}
catch (...)
{
tryAgain = ...
}
}
In this particular case there is nothing wrong with calling the same function recursively and keeping a counter with the number of times you've called it. Something like this (in pseudo code):
public void DoMyInternetThing(int numberOfAttemptsRemaining)
{
try
{
//do stuff
}
catch (ConnectionException)
{
if (numberOfAttemptsRemaining <= 0)
throw new SomethingBadHappenedException();
DoMyInternetThing(numberOfAttemptsRemaining - 1);
}
}
As with anything recursive you need to ensure you structure it correctly, but this works nicely (I've used it myself) and it avoids your goto (which is not bad in itself, but use of it can lead to spaghetti or badly structured code).
If you want to try again, wrap your try-catch in a do-while loop.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
It is important to me that my syntax does not make other developers confused.
In this example, I need to know if a parameter is a certain type.
I have hit this before; what's the most elegant, clear approach to test "not is"?
Method 1:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if (!(e.parameter is MyClass)) { /* do something */ }
}
Method 2:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if (e.parameter is MyClass) { } else { /* do something */ }
}
Method 3:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
var _Parameter = e.parameter as MyClass;
if (_Parameter != null) { /* do something */ }
}
Method 4:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
var _Type = typeof(MyClass);
switch (e.parameter.GetType())
{
case _Type: /* do nothing */; break;
default: /* do something */; break;
}
}
[EDIT] Method 5:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if ((e.parameter is MyClass) == false) { /* do something */ }
}
Which is the most straight-forward approach?
This is obviously a matter of personal opinion and style, so there's no right answer, but I think this is clearest:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if ((e.parameter is MyClass) == false) { /* do something */ }
}
The == false is just more obvious than the !
I would go for 3 if you need the variable later or 1 if you don't need the variable.
2 is ugly because of the empty block.
However I think they all are straight-forward.
I would think just making an extension method would be a clear way of doing it:
public static bool CannotBeCastAs<T>(this object actual)
where T: class
{
return (actual as T == null);
}
You then simply make a check like so:
if(myObject.CannotBeCastAs<SomeClass>())
{
}
Methods 1 and 3 would be my picks, depending on what I actually wanted.
Method 1 "does something" if and only if the passed object is not of the expected type. This means the passed object could be null and still pass.
Method 3 "does something" if the passed object is not of the expected type, OR if the object is null. This is basically a one-pass check that you have a "valid" instance of the class to work with further.
So, whether I wanted 1 or 3 depends on what I was planning to do. Usually, when the variable isn't of the expected type or is null, I want to throw an exception. If I were happy with throwing just one type of exception (say just an ArgumentException), I'd use method 3. If I wanted to check for null separately and throw an ArgumentNullException, I'd use method 1 and add the null check.
Method 2 is functionally correct, but I'd rather invert the if condition as in Method 1, as an if block that does nothing is redundant.
I would never do Method 4. A switch statement taking the place of a simple if-else is unnecessary and confusing, especially in the manner you're using it.
To me, Method 1 is the most straight-forward, both on its own and by convention. This is the syntax I've seen the most if you just need to know if an object "is-a" certain class.
If you actually need to do something with the object "as-a" certain class, then Method 3 is the way to go.
Method 1 is the best in my view. It's very obvious what the code is doing and I can follow right along. Method 2 introduces unnecessary syntax that is easily corrected by Method 1. Method 3 requires me to think more than the other two (marginally, but still!), and it also uses extra space that isn't needed.
Remember code is written for people to read, and only after for machines to execute. Go with clarity every time.
If you want elegance and readability:
void MyBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
bool isMyClass = e.parameter is MyClass;
if (!isMyClass) // or isMyClass == false
{
/* do something */
}
}
I've always tried my best not to put too much logic in a single line of code, specially if conditions. I think the type check and negation operator might be annoying to parse on first glance.
Method #5 (a different spin)
public static class TypeExtensions
{
public static bool IsNotTypeOf<T, X>(this T instance, X typeInstance)
{
return instance.GetType() != typeInstance.GetType();
}
}
// ...
if(e.parameter.IsNotTypeOf(MyClass)) { /* do something */ } ;
I would be of the opinion that braced functionality should always match whatever brace pattern is in use in your application. For instance, in the case of iteration or conditional blocks, if you use:
If (foo != bar)
{
//Do Something
}
well then this should be how you use brace patterned functionality at all times. One of my biggest bugbears with reading other peoples code (and this is especially true if they use CodeRush or Resharper) is the unnecessary terseness people add for no other reason than to display wizardry.
I am not saying the above is the best brace matching pattern however, use whatever one you feel comfortable with, what I would like to get across is that the pattern does not matter so much as the consistency of its use.
Personally, since C# is a terse language in comparison to, say VB.Net I would use long form statements or assignments (with the exception of var initialising) over more condense syntax to help aid later readability.
I like an approach used by one of the NUnit Assert's:
Assert.InstanceOf<MyType>(objectInstance);
BTW,
If you have a set of checks whether object is of specific type like:
if(objectInstance is TypeA)
{
// ...
}else
{
if(objectInstance is TypeC)
{
// ...
}
}
There should be some design issues like tied coupling between few types, so consider an other approach like injected map of associations or map like algorithm method per type
IDictionary<Type, Func<TParameter>>