I got the following code in my program:
#region Handle
if(HandleLink(input))
goto Handled;
else if(HandlePath(input))
goto Handled;
else if(HandleGeneratedLink(input))
goto Handled;
else ...
else
return; // Break if not handled
#endregion
Handled:
Im not very happy with this, because to me it seems like a cheat to use a goto in every second line.
Is there a common way to write such a thing or is this a valid solution?
You can also do something like this:
if (!HandleLink(input) && !HandlePath(input) && !HandleGeneratedLink(input)) {
return;
}
// put the code related to "Handled" here
You can do something like this:
if (HandleLink(input) || HandlePath(input) || HandleGeneratedLink(input)) {
// put the code below the "Handled" label here
} else {
return;
}
Since the || evaluates the right operand only if the left operand is false, HandlePath() will not be called when HandleLink() returns true. It works just like your if...else if statement!
Alternatively, you can make a variable called handled:
var handled = false;
if (HandleLink(input) || HandlePath(input) || HandleGeneratedLink(input)) {
handled = true;
} else {
return;
}
if (handled) {
// move the code below the "Handled" label here.
}
Try this
if(HandleLink(input) || HandlePath(input) || HandleGeneratedLink(input))
goto Handled;
else
return;
Related
The code below is a snippet from a working code that is for a castle maze game in c#.
The if else structure only prints correctly the dun.roomend == true). The tow.roomEnd now displays when the tre.isExit should be displayed. The tre.isExit doesn't display at all.
I have declared the current variables as:
public bool isExit;
public bool deadEnd;
public bool roomEnd;
tre.isExit = true;
dun.deadEnd = true;
tow.roomEnd = true;
if (dun.roomEnd == true)
{
Console.WriteLine("You've fallen into the Dungeons of the Dead. Try again");
return;
}
if (tow.roomEnd == true)
{
Console.WriteLine("You been caught by the Kings guard and have been placed in the tower for life.Try again");
return;
}
else if (tre.isExit == true)
{
Console.WriteLine("You have found the treaure... now run!!");
return;
}
else
{
Console.WriteLine("Too scared.....");
}
That's because you immediately return when one of your conditions is true.
// Don't explicitly compare to true - just write if (dun.roomEnd)
if (dun.roomEnd == true)
{
Console.WriteLine("You've fallen into the Dungeons of the Dead. Try again");
// You end the method here, so none of the rest of the code after this will execute
return;
}
Also, the fact that you do
else if (tre.isExit == true)
means that this won't execute if
tow.roomEnd == true
is also true. "Else if" means "if the current condition is true and the previous condition is false", so
if (A) {
// do work
}
else if (B) {
// Do work
}
is semantically equivalent to
if (A) {
// Do work
}
if (!A && B) {
// Do work
}
Finally, I mentioned this in passing, but I'd like to reiterate that it's not necessary to explicitly compare to true or false, so
if (tow.roomEnd == true)
should just be
if (tow.roomEnd)
Also, I don't think it makes sense for all of those conditions to be true at once. Can something actually be a room end, a dead end, and an exit at the same time? At a minimum, it seems like a particular location can't be both an exit and a dead end. If the data says that several of those things are true at once, it needs to be corrected in order for the program to function properly.
In every if statement you have keyword return;. The return statement terminates execution of the method and because of that only first Console.WriteLine is shown.
Read carefully: return (C# Reference)
Reading through what you've done, if I'm understanding this correctly what you're after is as follows.
public bool isExit;
public bool deadEnd;
public bool roomEnd;
tre.isExit = true;
dun.deadEnd = true;
tow.roomEnd = true;
if (dun.roomEnd == true)
{
Console.WriteLine("You've fallen into the Dungeons of the Dead. Try again");
}
else if (tow.roomEnd)
{
Console.WriteLine("You been caught by the Kings guard and have been placed in the tower for life.Try again");
}
else if (tre.isExit)
{
Console.WriteLine("You have found the treaure... now run!!");
}
else
{
Console.WriteLine("Too scared.....");
}
return
This will evaluate each condition individually, and then return once complete.
What this code is effectively saying is "if condition 1 is true, display the text and exit the if block, then return. Otherwise if condition 2 is true do the same, condition 3 / 4 do the same thing also.
I think this is what you're after at least. It could be refactored to make it a little simpler but don't have the time to go over that at the moment.
Assuming it is showing the Dungeons of the Dead and the Kings Guard message, you need to add an "else" to the if for tow.roomEnd.
How do I do this? I have an if-else statement like this (not exact code but a symbolic idea):
if(formNull)
{
MessageBox.Show("empty")
}
else if(FormNotNull)
{
// I have validation if/elses here for input fields like
if(regex textbx1)
{
error
}
else
{
normal
}
if(regex textbx2)
{
error
}
else
{
normal
}
//Some more like this
} <<<<<<<<<<<< It stops here and never goes in the next 'else' statement even if the form is OK.
else
{
DBConn.myMethod(a, b, c, etc.)
if true
{
success!;
}
else
{
failed!;
}
}
I tried some nesting combinations, but nothing worked.
Seems like there's nothing left, as you already handled all cases in the if and else if.
if(formNull)
{
// goes here when `formNull` is true
}
else if(FormNotNull)
{
// goes here when `FormNotNull` is true and `formNull` is false
}
else
{
// goes here in any other case (but I guess there is no other case left)
}
That just means your two conditions (in the if and else if statements) are returning true. If either ever returns true, you will never go into your else block (both MUST be false).
Thank you all for suggestions. I simply used the separate textChanged events with Regex for errors and used simple if-statement like this
if (FormNull)
{
Message.Show("error");
}
else
{
DBConn.myMthod(a,b,c)
if(true)
{
sucess;
}
else
{
failed;
}
}
Just wanted to know the other option for what I was trying to do.
Hey so I have all my code working and it's fine. But I'd like to clean it up a little.
At the moment I just have a message box show if there is an error in the input, so it would show "Please check your input", however I'd like it to show something like "Please check the following: firstname, secondname etc."
if ((FirstnameText.Text.Trim().Length == 0) || (SurnameText.Text.Trim().Length == 0)
|| (DateOfBirthText.Text.Trim().Length == 0) || (CourseText.Text.Trim().Length == 0)
|| (MatricNoText.Text.Trim().Length == 0) || (YearMarkText.Text.Trim().Length == 0)
|| (int.Parse(MatricNoText.Text) < 10000 || int.Parse(MatricNoText.Text) > 99999)
|| (int.Parse(YearMarkText.Text) < 0 || int.Parse(YearMarkText.Text) > 100))
{
errorMessage();
return;
}
public void errorMessage()
{
MessageBox.Show("Please check your input");
}
I know it's messy, but hey it works
Currently it just outputs that message, is there a simple way to output the specific textbox which has the error?
thanks
The built-in ErrorProvider component will work wonders for your situation. Drag it from the toolbox onto the designer for your form. It will appear at the bottom, where NotificationIcons and ContextMenuStrips appear. The great thing about the ErrorProvider is it give a visual feedback icon with a mouse over tooltip next to the control.
You can then use the "Validating" event of the control to check what you need:
private void FirstnameText_Validating (object sender, CancelEventArgs e)
{
string error = null;
if (FirstnameText.Text.Length == 0)
{
error = "You must enter a First Name";
e.Cancel = true; // This is important to keep focus in the box until the error is resolved.
}
ErrorProvider.SetError((Control)sender, error); // FirstnameText instead of sender to avoid unboxing the object if you care that much
}
You can also stick it in the Save button instead of raising it on the "Validating" event. To clean your code up even more, make a class that validates the input to keep non-UI stuff out of the UI.
Splitting up your code would be a start:
if ((FirstnameText.Text.Trim().Length == 0){
errorMessage("firstname is empty");
}
if (SurnameText.Text.Trim().Length == 0){
errorMessage("surname is empty");
}
Get the idea?
I often use Fluent Validation. The WithMessage method lets you specify an error message. The validator then returns you an enumerable of all error messages. There might also be a better fitting method for your specific problem.
If possible you re-write your code like below
Control errorControl =null;
foreach (Control ctrl in this.Controls)
{
if (ctrl is TextBox)
{
if (ctrl.Name == "MatricNoText")
{
if ((int.Parse(MatricNoText.Text) < 10000 || int.Parse(MatricNoText.Text) > 99999))
{
errorControl = ctrl;
}
}
else if (ctrl.Name == "MatricNoText")
{
if (int.Parse(YearMarkText.Text) < 0 || int.Parse(YearMarkText.Text) > 100)
{
errorControl = ctrl;
}
}
else
{
if (ctrl.Text.Length == 0)
{
errorControl = ctrl;
}
}
}
}
MessageBox.Show("Please check your input." + errorControl.Focus());
This is my javascript method in .aspx file. I want to invoke this method from code-behind based on a certain condition:
function confirmboxAndHideMessage() {
//HideMessage();
var response = confirm("are you sure?.");
if (response == true) {
document.getElementById("<%=chkValidated.ClientID%>").checked = true;
HideMessage();
}
else {
HideMessage();
return true;
}
}
The condition upon which I want to invoke is something like this:
if (obj.fkValidationStatusId.HasValue && obj.fkValidationStatusId.Value.Equals(1))
{
btnProceedAddNewRecords.Attributes.Add("OnClick", "javascript:return confirmboxAndHideMessage();");
}
else
{
btnProceedAddNewRecords.Attributes.Remove("OnClick");
}
This condition is being exercised in a method which is called in PageLoad event inside
if (!IsPostBack) { /* condition */ }
It is not working and my guess is that the way i am adding the method in button attribute is wrong. My request is that, kindly suggest a way I can invoke this javascript method from my code-behind based on the stated condition. If you think that my approach is flawed, Please do suggest Alternatives. Thanks.
use to set/unset OnClientClick
if (obj.fkValidationStatusId.HasValue && obj.fkValidationStatusId.Value.Equals(1))
{
btnProceedAddNewRecords.OnClientClick="return confirmboxAndHideMessage();";
}
else
{
btnProceedAddNewRecords.OnClientClick="retun false;";
}
Just add the following code where the condition is like
public void test()
{
String name = "test";
if (name == "test")
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "hdrEmpty", "if(confirm('are you sure you want to continue?')==true){ Testfunction(); };", true); return;
}
}
I am sure it will work for you.
You should return true or false from the function. You probably want to return true for a positive response:
function confirmboxAndHideMessage() {
var response = confirm("are you sure?.");
if (response == true) {
document.getElementById("<%=chkValidated.ClientID%>").checked = true;
HideMessage();
return true;
} else {
HideMessage();
return false;
}
}
Use lowercase for the event name (as XHTML is picky about that), and remove javascript: from the code:
btnProceedAddNewRecords.Attributes.Add("onclick", "return confirmboxAndHideMessage();");
Put the code that sets the attribute outside the check for IsPostBack, otherwise it will not be updated when the condition changes.
I have added one label in form that is not visible to user.Base on the text that label contain proceed further.
Here is my logic,but it fail.I wanted like this,if label contain "No match" or "Time out",should not proceed.
If((!label.Text.Contain("No match")) || label.Text.Contain("Time out"))
{
// proceed further code
}
else
{
// code
}
Here Label contain "No match",then it move to else part that is right.But when label contain "Time out",then it go inside the if loop.So I modified code like this
If((!label.Text.Contain("No match")) || (!label.Text.Contain("Time out")))
{
// proceed further code
}
else
{
// code
}
still not working.If label contain "Time out",still it go into if loop not else loop.Label contain only one text at a time either "No match" or "Time out" or any other text.
I suspect you want:
if(!(label.Text.Contains("No match") || label.Text.Contains("Time out")))
{
// proceed further code
}
else
{
// code
}
Note the bracketing. The inner part is
label.Text.Contains("No match") || label.Text.Contains("Time out")
and then that's inverted. I would probably pull that out into a separate variable:
bool timedOutOrNoMatch = label.Text.Contains("No match") ||
label.Text.Contains("Time out");
if (!timedOutOrNoMatch)
{
}
else
{
}
Alternatively, invert the sense of it:
if (label.Text.Contains("No match") || label.Text.Contains("Time out"))
{
// Do whatever was in your else block.
}
else
{
// Do whatever was in your first block.
}
If your response to the "bad" labels is something that lets you return or throw an exception, this can also reduce the amount of nesting:
if (label.Text.Contains("No match") || label.Text.Contains("Time out"))
{
output.Text = "Go away";
return;
}
// Now handle the success case
Try with following code:
if(!(label.Text.Contains("No match") || label.Text.Contains("Time out")))
{
// proceed further code
}
else
{
// code
}
If you want to get right with your modified code, use AND operator:
if(!label.Text.Contains("No match") && !label.Text.Contains("Time out"))
{
// proceed further code
}
else
{
// code
}
To write your code in more understood form , you should write it in a way that it is readable and more understandable. I prefer to write this statement like this
bool ProceedFurther()
{
//Don't proceed if No Match
if(!label.Text.Contains("No match")) return false;
//Don't proceed if Time out
if(!label.Text.Contains("Time out")) return false;
//Proceed otherwise
return true;
}
and call ProceedFurther method at desired location.
If you really want only that statement, following is the best (mostly people forget to change || to && after they change the condition to negative (using !).
if(!label.Text.Contains("No match") && !label.Text.Contains("Time out"))