Variable Declaration inside an IF C# - c#

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))
{
}

Related

if else operator is not running when it should

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.

How can I use a lambda expression in a while loop condition?

while(list.next() != null && list.next().asInteger() != 6)
{
...
}
Is it possible to use an inline lambda function here to avoid calling list.next() twice? If next() actually removed the element from the list, this would be essential not just convenient.
YourType foo;
while ((foo = list.next()) != null && foo.asInteger() != 6)
{
}
You can use for instead of while:
for (var item = list.next(); item != null && item.asInteger() !=6; item = list.next()) {
...
}
You can assign variables in while loops. It would be easier to write it like so.
WhateverNextReturns nextListItem;
while ((nextListItem = list.next()) != null) && nextListItem.asInteger() != 6)
// Do some stuff
Or better yet...
WhateverNextReturns nextListItem;
while(true)
{
nextListItem = list.next();
if (nextListItem == null || nextListItem == 6)
break;
//Do some stuff
}
I think using a lambda would make this more complex than what it has to be.
Here's another example in this StackOverflow Answer of someone assigning a variable in a while expression
It is possible to do this with an inline lambda, but C# does not like it:
while (((Func<YourType, bool>)(n => n != null && n.asInteger() != 6))(list.next()))
{
...
}
is this list an IEnumerable object? You can always use
list.Where(t!=null && t=>t.asInteger()==6).ToList().ForEach(t=>{
//do anything you want with t here.
});
Tell me if I got the question wrong.

c# Object reference not set to an instance of an object

I'm trying to work out if something does not exist in the table. I'm telling it to see if the UserInfo contains information for user.
UserInfo Character = db.UserInfoes.SingleOrDefault(a => a.Username == user);
if (Character.Username == null || Character.Username.Length == 0)
{
//do stuff
}
But I get an error on the if statement.
Object reference not set to an instance of an object.
It seems that the db.UserInfoes.SingleOrDefault(a => a.Username == user) expression returned null because it didn't find any matching records that satisfy the filter criteria.
so:
UserInfo Character = db.UserInfoes.SingleOrDefault(a => a.Username == user);
if (Character == null || Character.Username == null || Character.Username.Length == 0)
{
//do stuff
}
You wrote in the comments that you know that db.UserInfoes.SingleOrDefault(a => a.Username == user) returned null. Hence, Character is null and you need to check this case separately:
if (Character == null || // this line is new
Character.Username == null ||
Character.Username.Length == 0)
{
//do stuff
}
Since you say the error occurs on the if statement, Character is null. You need to add a check for if (Character == null).
First you should check whether Character is null, then later you should check for remaining in Character.
if(Character != null)
{
if(Character.Username == null || Character.Username.Lenght == 0)
{
//Do Stuff
}
}
EDIT:
or simply you can check only the Character, like
if(Character == null)
{
//Do Stuff
}
If you are getting an error on the if statement, then it is likely that your search:-
UserInfo Character = db.UserInfoes.SingleOrDefault(a => a.Username == user);
Has not found any record matching where Username equals user. When that happens, the value of Character is null.
Your issue is that you are trying to call a property on something that doesn't exist. You need to perform a check to ensure that Character is not null before calling any of its members.
if ( Character != null )
{
// Can now safely call properties on the Character object
}
else
{
// Take the appropriate action for circumstances where we can't
// find a user by username
}
You need to add a test on Character to know if it's null. If that's the case, you'll have the exception you mentionned.
So just do this :
if(Character != null)
{
//Your code can now safely call the Properties/Methods/etcetc...
}

Nested 'if'-'else' statements

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;
}
}

more short code about if statement

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.

Categories

Resources