Please check the code below. On first if section however all my conditions get false it's not going to else. Its always running the if inside codes.
To be more specific ViewBag.gtQuickDate this viewbag does not contain any value as shown below also other viewbags does not contain the value, then why it's not running the else if? Any mistake you found on operator then let me know.
if (ViewBag.subcattxt != "" & ViewBag.callFrom == "result" &
ViewBag.gtQuickDate != "2015y" || ViewBag.gtQuickDate != "2016y" ||
ViewBag.gtQuickDate != "2017y" || ViewBag.gtQuickDate != "blank")
{
}
else if (ViewBag.subcattxt != "" & ViewBag.callFrom == "result" &
ViewBag.gtQuickDate == "2015y" || ViewBag.gtQuickDate == "2016y" ||
ViewBag.gtQuickDate == "2017y" || ViewBag.gtQuickDate != "blank")
{
}
The reason for the condition evaluating incorrectly is that || has lower precedence than &, so any match of gtQuickDate renders the entire condition true.
It is generally a very bad idea to embed the current year into code, because it stops working as expected after a set period of time, requiring a recompile.
If you are looking for gtQuickDate from the last three years, you can do it like this:
int yearNow = DateTime.Now.Date.Year;
var blankOrLastThreeYears = new[] {
"blank"
, $"{yearNow - 0}y"
, $"{yearNow - 1}y"
, $"{yearNow - 2}y"
};
Now your condition can be rewritten as
if (ViewBag.subcattxt != ""
&& ViewBag.callFrom == "result"
&& blankOrLastThreeYears.Contains(ViewBag.gtQuickDate)) {
...
}
The list in blankOrLastThreeYears will contain entries for the last three years, and will update automatically for 2018, 2019, and so on.
I'm not certain what you're checking,if possible, could you separate ORs from ANDs, but please try:
if ((!(ViewBag.subcattxt.Equals(null)) && (!(ViewBag.callFrom.Equals("result"))) && (!(ViewBag.gtQuickDate.Equals("2015y"))))
{
//some other code
}
else if((!(ViewBag.gtQuickDate.Equals("2016y")) || (!(ViewBag.gtQuickDate.Equals("2017y")) || (!(ViewBag.gtQuickDate.Equals("blank"))))
{
//some other code
}
else if (ViewBag.subcattxt.Equals(null) && ViewBag.callFrom.Equals("result") && ViewBag.gtQuickDate.Equals("2015y"))
{
//some other code
}
else if(ViewBag.gtQuickDate.Equals("2016y") || ViewBag.gtQuickDate.Equals("2017y") || ViewBag.gtQuickDate.Equals("blank"))
{
//other code
}
Hope this helps.
Related
I am stuck on what I thought would be a really easy problem. I am trying to redirect a user to a different website if the UserAgent does not contain a series of strings. The part I can not figure out is that the if statement works fine if I use the code below. I am happy with the results with this but something tells me that it is not good practice to only have an else statement and perform nothing if the statement proves to be true.
string strUserAgent = Request.UserAgent.ToString().ToLower();
if (strUserAgent != null)
{
if (Request.Browser.IsMobileDevice == true ||
strUserAgent.Contains("iphone") ||
strUserAgent.Contains("blackberry") ||
strUserAgent.Contains("mobile") ||
strUserAgent.Contains("windows ce") ||
strUserAgent.Contains("opera mini") ||
strUserAgent.Contains("palm") ||
strUserAgent.Contains("android"))
{
// Is this normal practice to only have an else block?
}else
{
Response.Redirect(AppState["redirectBack"].ToString());
}
When I try the next block of code the script redirects the user no matter what the UserAgent string contains. Can someone explain why this might be happening?
string strUserAgent = Request.UserAgent.ToString().ToLower();
if (strUserAgent != null)
{
if (Request.Browser.IsMobileDevice != true ||
!strUserAgent.Contains("iphone") ||
!strUserAgent.Contains("blackberry") ||
!strUserAgent.Contains("mobile") ||
!strUserAgent.Contains("windows ce") ||
!strUserAgent.Contains("opera mini") ||
!strUserAgent.Contains("palm") ||
!strUserAgent.Contains("android"))
{
Response.Redirect(AppState["redirectBack"].ToString());
}
You need De Morgan's Law. When you inverted your condition, your ORs need to become ANDs
Invert your statement using ! ("not"):
if(!(conditions)) { }
This will avoid the need to use an empty code block and you can just drop the else.
Your second codeblock will redirect when you're not on a mobile device or when your useragent contains any of the following strings. It depends on your input and your environment.
Do note that it's a lot easier to create a collection of the possibilities and check if your useragent is in there:
if(new[] {"iphone", "somephone", "otherphone" }.Any(x => useragent.Contains(x))) {}
It will always be true that at least one of your conditions will not be true. For instance, if strUserAgent.Contains(iphone) will be false if strUserAgent.Contains("blackberry") is true.
You need to change your OR (||) operator to a logical AND (&&) operator.
if (strUserAgent != null)
{
if (Request.Browser.IsMobileDevice != true &&
!strUserAgent.Contains("iphone") &&
!strUserAgent.Contains("blackberry") &&
!strUserAgent.Contains("mobile") &&
!strUserAgent.Contains("windows ce") &&
!strUserAgent.Contains("opera mini") &&
!strUserAgent.Contains("palm") &&
!strUserAgent.Contains("android"))
{
Response.Redirect(AppState["redirectBack"].ToString());
}
Not an answer, just a suggestion. You can make your code cleaner with an extension method:
public static bool ContainsAnyOf(this string source, params string[] strings)
{
return strings.Any(x => source.Contains(x));
}
And now write
if (strUserAgent.ContainsAnyOf("iphone", "blackberry", "mobile", "windows ce", "opera mini", "palm", "android"))
{
//
}
You need to reverse the entire thing. Putting !A || !B is not the same as !(A||B). In the first one if its A then it's Not B so it's True. In the second one it's False.
if (!(Request.Browser.IsMobileDevice == true ||
strUserAgent.Contains("iphone") ||
strUserAgent.Contains("blackberry") ||
strUserAgent.Contains("mobile") ||
strUserAgent.Contains("windows ce") ||
strUserAgent.Contains("opera mini") ||
strUserAgent.Contains("palm") ||
strUserAgent.Contains("android")
) )
{
Response.Redirect(AppState["redirectBack"].ToString());
}
string strUserAgent = Request.UserAgent.ToString().ToLower();
if (strUserAgent != null)
{
if (!(Request.Browser.IsMobileDevice == true ||
strUserAgent.Contains("iphone") ||
strUserAgent.Contains("blackberry") ||
strUserAgent.Contains("mobile") ||
strUserAgent.Contains("windows ce") ||
strUserAgent.Contains("opera mini") ||
strUserAgent.Contains("palm") ||
strUserAgent.Contains("android")))
{
Response.Redirect(AppState["redirectBack"].ToString());
}
Is there a way to tell the program that i don't care if a class reference is null.
For example:
if (playermove[i].name == "punch" || ispunchactivated == true)
{
Do the punch;
}
Why is he searching for the playermove (that can be null) and give me a null exeption error? i really don't care if the ispunchactivated is true.
Thanks.
If you put your two conditions the other way around:
ispunchactivated /*== true*/ || playermove[i].name == "punch"
// this isn't necessary
then, if the first one is true, the second one won't be checked.
However, unless you know playermove[i] won't be null if ispunchactivated is false, you should really be making the null check too, otherwise you'll still get exceptions:
ispunchactivated ||
(playermove[i] != null && playermove[i].name == "punch")
You just check it for null first.
There are not shortcuts here.
if (playermove == null || playermove[i].name == "punch" || ispunchactivated == true)
{
Do the punch;
}
Try this,
if ((ispunchactivated == true) || (playermove[i] != null && playermove[i].name == "punch" ))
{
Do the punch;
}
You can modify the if condition as follows:
if (ispunchactivated == true || (playermove!=null && playermove[i].name == "punch" ))
Just interchange the conditions and shortcircuitting will do that for you:
if (ispunchactivated == true || playermove[i].name == "punch")
{
Do the punch;
}
playermove[i] is only evaluated if ispunchactivated is false. That being said, you can still run into a null pointer exception if ispunchactivated is false and playermove[i] is null.
Change your condition as follows:
if(playermove !=null && playermove[i] != null)
{
if (playermove[i].name == "punch" || ispunchactivated == true)
{
Do the punch;
}
}
take a look at the following code :
if( down == null || down.GetFace() != Face.None || down.GetFace() != Face.Partial )
{
// I called GetFace() two times
// How can i avoid to call it two times, and still putting inside that if
}
Thank you!
To be more maintainable and expressive first separate the null check as exceptional case
then get the result to a variable and check it.
if(down == null)
// Some exceptional case .. return or throw exception
var result = down.GetFace();
if(result == Face.None || result != Face.Parial)
// Do your code here
Refactor to a method:
private bool IsFaceNoneOrPartial(Down down)
{
var face = down.GetFace();
return face != Face.None || face != Face.Partial;
}
// Your code is now:
if( down == null || IsFaceNoneOrPartial(down))
{
}
I have code that's very messy with the if - else if checks it is doing. The amount of branching and nested branching is quite big (over 20 if - else if and nested too). It's making my code harder to read and will probably be a performance hog. My application checks for a lot of conditions it gets from the user and so the application must check all the time for different situations, for example:
If the textbox text is not 0, continue with the next...
if ((StartInt != 0) && (EndInt != 0))
{
And then here it checks to see whether the user have choosen dates:
if ((datePickerStart.SelectedDate == null) || (datePickerEnd.SelectedDate == null))
{
MessageBox.Show("Please Choose Dates");
}
Here, if the datepickers aren't null it continues with code...
else if ((datePickerStart.SelectedDate != null) && (datePickerEnd.SelectedDate != null))
{
// CONDITIONS FOR SAME STARTING DAY AND ENDING DAY.
if (datePickerStart.SelectedDate == datePickerEnd.SelectedDate)
{
if (index1 == index2)
{
if (StartInt == EndInt)
{
if (radioButton1.IsChecked == true)
{
printTime3();
}
else
{
printTime();
}
}
This is just a small part of the checks being made. Some of them are functionals and some are for input validation stuff.
Is there any way to make it more readable and less of a performance hog?
It's not that of a performance hog. A great blog post on how to fix those common problems is Flattening Arrow Code.
I see here some mix in validation. Try to move one fields from others, and validate them separately, something like this:
if (StartInt == 0 || EndInt == 0)
{
MessageBox.Show("Please Choose Ints");
return;
}
if (datePickerStart.SelectedDate == null || datePickerEnd.SelectedDate == null)
{
MessageBox.Show("Please Choose Dates");
return;
}
In this approach you'll always say to the user what he did wrong, and your code is much simpler.
More information from Jeff's blog
One way is to refactor by encapsulating complex conditions in the following way:
public bool DateRangeSpecified
{
get
{
return (datePickerStart.SelectedDate != null)
&&
(datePickerEnd.SelectedDate != null)
&& StartInt != 0 && EndInt != 0;
}
}
and then using these "condition facade" properties
Some slight refactoring makes it easier to read to my eyes. I removed extraneous brackets and consolidated multiple IF statements that are really just AND logic.
if (StartInt == 0 || EndInt == 0)
return;
if (datePickerStart.SelectedDate == null || datePickerEnd.SelectedDate == null)
{
MessageBox.Show("Please Choose Dates");
return;
}
if (datePickerStart.SelectedDate != null
&& datePickerEnd.SelectedDate != null
&& datePickerStart.SelectedDate == datePickerEnd.SelectedDate
&& index1 == index2
&& StartInt == EndInt)
{
if (radioButton1.IsChecked == true)
printTime3();
else
printTime();
}
You can define your own predicates or generic functions with meaningful names and encapsulate you logic into those.
Here is a code example for some predicates:
public Predicate<DateTime> CheckIfThisYear = a => a.Year == DateTime.Now.Year;
public Func<DateTime, int, bool> CheckIfWithinLastNDays = (a, b) => (DateTime.Now - a).Days < b;
Now you can easily write in your code
if (CheckIfThisYear(offer) && CheckIfWithinLastNDays(paymentdate,30)) ProcessOrder();
Consider using generic delegates, like Func<> and Delegate<> for writing small blocks of your conditions using lambda-expressions -- it will both save the space and makes your code much more human-readable.
Use the return statement to stop the execution of a block.
For instance,
void Test()
{
if (StartInt==0 || EndInt==0)
{
return;
}
if (datePickerStart.SelectedDate == null || datePickerEnd.SelectedDate == null)
{
MessageBox.Show("Please Choose Dates");
return;
}
}
i wanted to try the following code:
//all arrays are List<T> type.
if (m.terms[0] != null && m.terms[0].labels != null && m.terms[0].labels[0].title == "Part-of-speech")
{
result = true;
}
but it occured runtime error occasionly in following situation
i. m.terms == null
ii. m.terms != null, but m.terms[0] does not intialized.
iii. m.terms != null, and m.terms[0] has been exist but
m.terms[0].label does not initialized.
...
so i did modify it to like this:
if (m.terms[0] != null)
{
if (m.terms[0].labels != null)
{
if (m.terms[0].labels[0].title == "Part-of-speech") { result = true; }
}
}
is it the best way?
&& is a short circuiting operator, so the first way you wrote it and the second way will be functionally equivalent.
if (a && b && c)
{
// work
}
b will only be evaluated if a returns true. (Same goes for c).
In your code, checking m.terms[0].labels will not be a problem because you would have short-circuited out of the expression if m.terms[0] had been null.
To completely cover yourself, you'd want to possibly add checks for m and m.terms, however.
m != null && m.terms != null && m.terms.Count > 0 && m.terms[0] != null ...
As it evaluates from left to right, it will break on the first condition that doesn't pass and the rest will go unchecked.
int index = 0;
int labelIndex = 0;
string titleToCheck = "Part-of-speech";
if (m != null && m.terms != null && m.terms.Count > index)// or m.Length...
{
if (m.terms[index] != null && m.terms[index].labels != null &&
m.terms[index].labels.Count > labelIndex)
{
if (m.terms[index].labels[labelIndex].title == titleToCheck)
{
result = true;
}
}
}
This is all about readability. C# uses Short-circuit evaluation so in functionality there is no difference.
try this
if (m!=null && m.terms!= null && m.terms[0].labels!=null && m.terms[0].labels[0].title!=null && m.terms[0].labels[0].title == "Part-of-speech")
Yes, it would be better to split off each null check into a separate if statement.
The reason is that the second and third conditions require the first to not be null. If the first is null, then the second and third conditions will in turn throw errors because their parent is null yet is trying to be accessed.