I'm trying to break a forloop using break as traditional, but in this case I find myself stuck with this nested switch where the break only works into the switch scope and the loop keeps iterating.
for (int i = 0; i < lenght; i++)
{
switch (enum)
{
case Enum.some_1: break;
case Enum.some_2: break;
case Enum.some_3: break;
}
}
There are multiple options to approach this:
Using helper variable
bool exit = false;
for (int i = 0; i < length && !exit; i++)
{
switch(enum)
{
case Enum.case_which_breaks:
exit = true;
break;
// other cases
}
// some other code, which may use `i`
}
Using helper method
This would be simpler, if you could refactor out the whole for block into a helper method. In this case, you'll use return rather than break.
private Result HandleInternally(int length, Enum enum, Request params)
{
for (int i = 0; i < length; i++)
switch (enum)
{
case Enum.case_which_breaks:
Result result = new Result(); //populate the result
return result;
// other cases
}
}
And then in the consuming code simply call the method.
bool exitForLoop = false;
for (int i = 0; i < length && !exitForLoop; i++)
{
switch (enum)
{
case Enum.some_1: exitForLoop = true; break;
case Enum.some_2: break;
case Enum.some_3: break;
}
}
bool exit = false;
int i = 0;
while (!exit && i < length)
{
switch (enum)
{
case Enum.some_1: exit = true; break;
case Enum.some_2: exit = true; break;
case Enum.some_3: exit = true; break;
}
i++;
}
Related
Together with a friend, we are trying to create a sea battle for playing on a local network, we made a field of buttons, created islands on it, you can set up ships and move them. But when we connected the form to our server, after requesting the package, the form stops drawing buttons, they store the correct data, but their visual update does not occur
Here are the pieces of code
private void button1_Click(object sender, EventArgs e)
{
comboBox1.Visible = false;
comboBox2.Visible = false;
button1.Visible = false;
comboBox3.Visible = false;
button2.Visible = true;
SendPacket(PacketInfo.SendGameInfo);
Thread thread = new Thread(FightIsDone);
thread.Start();
State = GameState.Waiting;
}
void FightIsDone()
{
ReceivePacket();
this.Invoke(new Action(() => GameUpdate()));
}
public void GameUpdate()
{
Console.WriteLine("!");
State = GameState.Planing;
foreach (Ship ship in Ships)
{
ship.UseModuls();
}
SetShip(Ships);
UpdateSight();
Draw();
}
The problem is here, this method changes the image of the button or its color, it works fine until the packet is sent to the server, but after receiving it, only the information is updated, and the appearance of the form does not change
public void Draw()
{
foreach (CellButton Butt in Field)
{
if (Butt.Sigth)
{
Butt.Image = null;
SetImage(Butt);
}
else
{
Butt.BackColor = Color.Gray;
Butt.Image = null;
}
}
}
public void SetImage(CellButton Butt)
{
switch (Butt.Entety)
{
case GameObject.Water: Butt.BackColor = Color.DodgerBlue; break;
case GameObject.Island: Butt.Image = GetObjectImage(GameObject.Island); break;
case GameObject.Ship:
{
Butt.Image = Butt.modul.ModulImage;
break;
}
case GameObject.Torpedo: Butt.BackColor = Color.DarkBlue; break;
case GameObject.Fire: Butt.Image = GetObjectImage(GameObject.Fire); break;
}
}
static void SendPacket(PacketInfo info)
{
ms.Position = 0;
switch (info)
{
case PacketInfo.Connect:
writer.Write(0);
break;
case PacketInfo.SendCoordinate:
writer.Write(1);
formatter.Serialize(ms, new Coordinate(5, 0));
break;
case PacketInfo.LaunchSearch:
writer.Write(2);
writer.Write(Me.ID);
break;
case PacketInfo.SendGameInfo:
writer.Write(3);
writer.Write(Me.ID);
List<Ship> shpooks = new List<Ship>();
foreach (Ship s in Ships)
if (s.PlayerID == Me.ID) shpooks.Add(s);
formatter.Serialize(ms, shpooks);
break;
}
socket.Send(ms.GetBuffer());
}
static int ReceivePacket()
{
ms.Position = 0;
socket.Receive(ms.GetBuffer());
int code = reader.ReadInt32();
switch (code)
{
case 0:
{
Console.WriteLine("Catch");
Console.WriteLine(ms.ToString());
bool IsConected = reader.ReadBoolean();
if (IsConected)
{
Me.ID = reader.ReadInt32();
return 1;
}
break;
}
case 2:
{
return 1;
break;
}
case 3:
{
Cell[,] cells = (Cell[,])formatter.Deserialize(ms);
for (int i = 0; i < Width; i++)
for (int j = 0; j < Hight; j++)
{
Field[i, j] = new CellButton(new Coordinate(i, j));
Field[i, j].SetCell(cells[i, j]);
}
Ships.Clear();
Ships.AddRange((List<Ship>)formatter.Deserialize(ms));
break;
}
}
return -1;
}
This is the form before calling Draw():
This is how the form looks after calling Draw():
And so, after a request to the server and method Draw():
I spent a lot of time finding solutions, methods like Form.Update() and Form.Refresh() don't help
This is a sample of my code. I want to have a 3 second delay before executing the next case (display picturebox). But When I tried using timer/stopwatch, the 3 second delay will only be on the 1st case and case2 will execute the same time as case1 (with no delay).
private void button1_Click(object sender, EventArgs e)
{
string input = (input1.Text).ToString();
char[] letters = input.ToCharArray();
int stringlength = letters.Length;
int length = stringlength - 1;
int state = 1;
int position = 0;
string validation = " ";
switch (state)
{
case 1:
//insert timer here
if (letters[position] == 'a')
{
pictureBox2.Visible = true;
validation = "Invalid";
label1.Text = validation;
break;
}
else if (letters[position] == 'b')
{
if (position == length)
{
validation = "Invalid";
label1.Text = validation;
break;
}
pictureBox2.Visible = true;
position = position + 1;
goto case 2;
}
break;
case 2:
//Insert Timer here
if (letters[position] == 'a')
{
pictureBox3.Visible = true;
if (position == length)
{
validation = "Invalid because it does not end at final state";
label1.Text = validation;
break;
}
position = position + 1;
goto case 3;
}
else if (letters[position] == 'b')
{
if (position == length)
{
validation = "Invalid";
label1.Text = validation;
break;
}
position = position + 1;
goto case 4;
}
break;
}
}
By the way, I can't use Task.Delay or async/await because I use the .Net 4.0 framework.
You can perform this by using:
System.Threading.Thread.Sleep(3000);
So Your code should look like:
private void button1_Click(object sender, EventArgs e)
{
int state = 1;
//some code
switch (state)
{
case 1:
System.Threading.Thread.Sleep(3000);
//some case code
break;
case 2:
System.Threading.Thread.Sleep(3000);
//some case code
break;
default:
System.Threading.Thread.Sleep(3000);
//some default code
break;
}
//rest of the code
}
Just to let You know, there should be other (and better) way to going through this, rather than using switch and this type of GOTO case this and this. Making the code unreadable in future.
Thread.Sleep(3000) you can use
I recently "finished" a new project except there is a small problem. Im not getting my results back.
This project utilizes c# web services via a SOAP client along with Request and Response Classes. The project is designed to reserve something, in this demo, it reserves a seat in a cinema. However when the data is passed from the windows form client to the web service, nothing comes back. I recently stopped the project from freezing upon execution of the web method.
This is the method that calls the web service (The method signature is only temporary)
public void derp()
{
var client = new SampleServiceSoapClient();
var req = new GetReservationRequest();
req.row = row;
req.seat = seat;
req.name = textNameRequest.Text;
try
{
client.GetReservation(req);
}
catch (Exception err)
{
MessageBox.Show("Server Unavailable");
}
}
I am running this method on a seperate thread to stop crashing. The output of this method is supposed to come back through a response object and then i assign the values of said object to text boxes on the form. However, the data is lost before it returns.
The web method is as follows
[WebMethod]
public GetReservationResponse GetReservation(GetReservationRequest req)
{
object o = HttpContext.Current.Cache["Reservation"];
if(o == null)
{
o = reservedSeat;
}
else
{
reservedSeat = (bool[,])o;
}
GetReservationResponse resp = new GetReservationResponse();
string rowHolder = "A";
int rowRequest = req.row;
int seatCopy = 0;
bool emptySeat = false;
while (rowRequest < 12)
{
for (int seat = req.seat; seat < 16; seat++)
{
if (reservedSeat[req.row, seat])
{
//Loop back
}
else
{
emptySeat = true;
seatCopy = seat;
break;
}
}
if (reservedSeat[req.row, 15])
{
seatCopy = 0;
break;
}
}
switch (rowRequest)
{
case 1: rowHolder = "A";
break;
case 2: rowHolder = "B";
break;
case 3: rowHolder = "C";
break;
case 4: rowHolder = "D";
break;
case 5: rowHolder = "E";
break;
case 6: rowHolder = "F";
break;
case 7: rowHolder = "G";
break;
case 8: rowHolder = "H";
break;
case 9: rowHolder = "I";
break;
case 10: rowHolder = "J";
break;
case 11: rowHolder = "K";
break;
case 12: rowHolder = "L";
break;
default: rowHolder = "None Specified";
break;
}
int x = 0;
if (!reservedSeat[rowRequest, seatCopy])
{
reservedSeat[rowRequest, seatCopy] = true;
seatCopy++;
//resp.row = rowRequest;
x = seatCopy;
seatCopy--;
if (seatCopy.Equals(15))
{
rowRequest++;
}
}
resp.row = rowHolder;
resp.seat = x;
//row++
return resp;
}
I have no clue why the data is being lost before it comes back but some information would be amazing...
Where in this code rowrequest is incremented? It seems to me, that you have infinite loop here:
while (rowRequest < 12)
{
for (int seat = req.seat; seat < 16; seat++)
{
if (reservedSeat[req.row, seat])
{
//Loop back
}
else
{
emptySeat = true;
seatCopy = seat;
break;
}
}
if (reservedSeat[req.row, 15])
{
seatCopy = 0;
break;
}
}
I use ILSpy and .NET Reflector to see code, and I found code I don't understand it, I serach in the web and I don't found any1 can help how to resolve it.
This code with ILSpy (.NET Reflector show the same)
private void Item_Clicked(object sender, EventArgs e)
{
switch (0)
{
case 0:
{
IL_0E:
FileSystemItem fileSystemItem;
while (true)
{
fileSystemItem = (sender as FileSystemItem);
int num = 1;
while (true)
{
switch (num)
{
case 0:
if (<PrivateImplementationDetails>{4E2292E7-C82C-431F-9529-B0045F4C1457}.$$method0x60003e4-1 != null)
{
goto IL_25F;
}
if (true)
{
IL_163:
num = 3;
continue;
}
goto IL_163;
case 1:
if (fileSystemItem != null)
{
num = 11;
continue;
}
return;
case 2:
goto IL_3B8;
case 3:
{
Dictionary<string, int> expr_1B9 = new Dictionary<string, int>(9);
expr_1B9.Add(".mp3", 0);
expr_1B9.Add(".wav", 1);
expr_1B9.Add(".wma", 2);
expr_1B9.Add(".wmv", 3);
expr_1B9.Add(".avi", 4);
expr_1B9.Add(".jpg", 5);
expr_1B9.Add(".png", 6);
expr_1B9.Add(".txt", 7);
expr_1B9.Add(".inf", 8);
<PrivateImplementationDetails>{4E2292E7-C82C-431F-9529-B0045F4C1457}.$$method0x60003e4-1 = expr_1B9;
num = 15;
continue;
}
case 4:
{
string ext;
if ((ext = fileSystemItem.Ext) != null)
{
num = 8;
continue;
}
return;
}
case 5:
goto IL_2C9;
case 6:
num = 12;
continue;
case 7:
{
string ext;
int num2;
if (<PrivateImplementationDetails>{4E2292E7-C82C-431F-9529-B0045F4C1457}.$$method0x60003e4-1.TryGetValue(ext, ref num2))
{
num = 6;
continue;
}
return;
}
case 8:
num = 0;
continue;
case 9:
goto IL_25A;
case 10:
goto IL_36A;
case 11:
num = 14;
continue;
case 12:
{
int num2;
switch (num2)
{
case 0:
case 1:
case 2:
num = 16;
continue;
case 3:
case 4:
goto IL_171;
case 5:
case 6:
goto IL_1A4;
case 7:
case 8:
this.ShowText(fileSystemItem.Path);
num = 9;
continue;
default:
num = 13;
continue;
}
break;
}
case 13:
return;
case 14:
if (fileSystemItem.IsFolder)
{
switch ((1 == 1) ? 1 : 0)
{
case 0:
case 2:
goto IL_36F;
case 1:
IL_2B7:
if (false)
{
IL_2BD:
num = 5;
continue;
}
goto IL_2BD;
}
goto IL_2B7;
}
num = 4;
continue;
case 15:
goto IL_25F;
case 16:
if (fileSystemItem.IsPlaying)
{
num = 10;
continue;
}
goto IL_36F;
}
break;
IL_25F:
num = 7;
continue;
IL_36F:
BackgroundAudioPlayer.get_Instance().set_Track(new AudioTrack(new Uri(fileSystemItem.Path, 2), "Unknown", "Unknown", "Unknown", null));
IEnumerator<object> enumerator = this.filesListBox.get_Items().GetEnumerator();
num = 2;
}
}
IL_131:
BackgroundAudioPlayer.get_Instance().Stop();
fileSystemItem.IsPlaying = false;
return;
IL_171:
MediaPlayerLauncher mediaPlayerLauncher = new MediaPlayerLauncher();
mediaPlayerLauncher.set_Media(new Uri(fileSystemItem.Path, 2));
mediaPlayerLauncher.set_Location(2);
mediaPlayerLauncher.Show();
return;
IL_1A4:
this.ShowImage(fileSystemItem.Path);
return;
IL_25A:
return;
IL_2C9:
this.ShowFolderContents(fileSystemItem.Path);
return;
IL_36A:
goto IL_131;
IL_3B8:
try
{
int num = 2;
while (true)
{
switch (num)
{
case 0:
num = 1;
continue;
case 1:
goto IL_EC;
case 3:
{
IEnumerator<object> enumerator;
if (!enumerator.MoveNext())
{
num = 0;
continue;
}
FileSystemItem fileSystemItem2 = (FileSystemItem)enumerator.get_Current();
fileSystemItem2.IsPlaying = false;
num = 4;
continue;
}
}
IL_A7:
num = 3;
continue;
goto IL_A7;
}
IL_EC:
goto IL_23A;
}
finally
{
int num = 2;
while (true)
{
IEnumerator<object> enumerator;
switch (num)
{
case 0:
goto IL_12E;
case 1:
enumerator.Dispose();
num = 0;
continue;
}
if (enumerator == null)
{
break;
}
num = 1;
}
IL_12E:;
}
goto IL_131;
IL_23A:
fileSystemItem.IsPlaying = true;
return;
}
}
goto IL_0E;
}
the error of this dictionnary show me this error
<PrivateImplementationDetails>{4E2292E7-C82C-431F-9529-B0045F4C1457}.$$method0x60003e4-1
So, this what? and how Can I resolve that?
I need to replace it with another variable or what?
<PrivateImplementationDetails>{4E2292E7-C82C-431F-9529-B0045F4C1457} is not a proper C# construct. This is perhaps a substitute name which ILSpy issues to some internal framework function, which is not supposed to be used by ordinary developers.
So you need to reverse-engineer the code and understand what does it really do. And implement it by some other means. You cannot just take it and use it :)
By the way, the code seems to be an obfuscated one, while there are lots of unnecessary instructions there. In your case, the whole loop/switch codes a state machine in a fancy way. (It could be that its execution is always sequential, so you ought to try tracing it manually -- with paper and pencil. Try it, it's fun!)
This question already has answers here:
Break out of a while loop that contains a switch statement
(15 answers)
Closed 9 years ago.
I have a code snippet :
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
break;
break;//This is unreachable and so i cannot Terminate the For Loop within the SWITCH
}
}
As described in a comment I cannot terminate the For Loop directly from the Switch, only if I declare a boolean and at the End of Switch test
if(LoopShouldTerminate)
break;
PS : or maybe I'm very confused!
[POST]
I got the message ,and the problem is Solved ,but i would like to asume that using Switch within a for loop isn't a god idea ,because i heard from lot of developer's i should break from loop in the moment when i get the desired result ,so using switch need's extra boolean or push the Int i value to 50 direclty , but what would happen if we're using while loop ?
Solution 1: Move the loop and the switch to different methods:
for(int i = 0; i < 50; ++i)
{
if (DoCheckStatus(i)) break;
}
...
bool DoCheckStatus(int i)
{
switch(CheckStatus(i))
{
case 1 : return true;
default: return false;
}
}
Solution 2: Adapt the above to eliminate the loop with an eager extension method:
static void DoWhile<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
foreach(T item in sequence)
if (!predicate(item)) return;
}
...
Enumerable.Range(0, 50).DoWhile(DoCheckStatus)
Solution 3: Adapt the above to eliminate the loop and the helper method:
Enumerable.Range(0, 50).DoWhile(i=>
{
switch(CheckStatus(i))
{
case 1 : return true;
default: return false;
}
});
You can use goto in order to break out of the loop within the switch.
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
goto outofloop;
}
}
:outofloop
// more code
One of the few good uses of goto...
Just change the value of i:
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
i += 50;
break;
}
}
If there is no other code after the switch you can just check in the for loop itself whether to continue looping:
bool doContinue = true;
for (int i = 0; i < 50 && doContinue; i++)
{
n = checkStatus();
switch (n)
{
case 1:
doContinue = false;
}
}
Can you place the loop inside of a method and just use return?
Example:
myLoopingMethod()
{
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
return;
}
}
}
Another option would be to use a traditional if/else instead of a switch/case. Then you can just use break and it will jump out of your for loop
You could use a boolean.
int n = 0;
for (int i = 0; i < 50; i++)
{
bool shouldBreak = false;
n = checkStatus();
switch (n)
{
case 1:
shouldBreak = true;
break;
}
if (shouldBreak)
break;
}
I don't know if there's other logic that needs to be performed after the loop is finished, but you could try using return instead. The other option is to set a boolean flag, and exit after the switch.
switch (n)
{
case 1:
return;
}
This smells of bad design; there are a couple of ways you could fix this:
If only one condition of your switch would break the outer loop, then simply check for that before entering the switch:
if(n == 1)
break;
switch(n) { }
If multiple conditions can break the loop, refactor to a more linq style query:
Enumerable.Range(0, 50).FirstOrDefault(x => listOfBreakCodes.Contains(checkStatus());
That should call checkStatus up to 50 times until it encounters a 1 (or other break codes), and then doesnt continue evaluating elements.