Nully the null error - c#

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

Related

Simplify conditional if statement c#

I have an if statement that becoming a bit cumbersome. I want to know if there's a better way of going about multiple similar if statements such as combining into one or using a different conditional statement such as a while or do loop. Any suggestions are appreciated.
if (options.OpenCloseOverridesOptions != null && !options.OpenCloseOverridesOptions.AreEqual(OpenCloseOverridesOptions))
return false;
if (options.DeliveryOpenCloseOverridesOptions != null && !options.DeliveryOpenCloseOverridesOptions.AreEqual(DeliveryOpenCloseOverridesOptions))
return false;
if (options.PickupOpenCloseOverridesOptions != null && !options.PickupOpenCloseOverridesOptions.AreEqual(PickupOpenCloseOverridesOptions))
return false;
if (options.PickupServiceWindowOverridesOptions != null && !options.PickupServiceWindowOverridesOptions.AreEqual(PickupServiceWindowOverridesOptions))
return false;
if (options.DeliveryServiceWindowOverridesOptions != null && !options.DeliveryServiceWindowOverridesOptions.AreEqual(DeliveryServiceWindowOverridesOptions))
return false;
if (options.ServiceWindowOverridesOptions != null && !options.ServiceWindowOverridesOptions.AreEqual(ServiceWindowOverridesOptions))
return false;
if (options.LineItemsOptions != null && !options.LineItemsOptions.AreEqual(LineItemsOptions))
return false;
the rundown is I am basically checking if an object is null, if not use an extension method to determine if a similar object is equal. (I'm not overriding isEquals and getHashCode ). if the object is null I cannot call the areEquals extension method so that check is necessary.
If you want to return bool you can return the condition directly.
We can use another skill (De Morgan's laws) let! into the statement, that will reverse all logic, let the code more clear.
return
(options.OpenCloseOverridesOptions == null || options.OpenCloseOverridesOptions.AreEqual(OpenCloseOverridesOptions)) &&
(options.DeliveryOpenCloseOverridesOptions == null || options.DeliveryOpenCloseOverridesOptions.AreEqual(DeliveryOpenCloseOverridesOptions)) &&
(options.PickupOpenCloseOverridesOptions == null || options.PickupOpenCloseOverridesOptions.AreEqual(PickupOpenCloseOverridesOptions))&&
(options.PickupServiceWindowOverridesOptions == null || options.PickupServiceWindowOverridesOptions.AreEqual(PickupServiceWindowOverridesOptions) &&
(options.DeliveryServiceWindowOverridesOptions == null || options.DeliveryServiceWindowOverridesOptions.AreEqual(DeliveryServiceWindowOverridesOptions)&&
(options.ServiceWindowOverridesOptions == null || options.ServiceWindowOverridesOptions.AreEqual(ServiceWindowOverridesOptions)&&
(options.LineItemsOptions == null || options.LineItemsOptions.AreEqual(LineItemsOptions)
Try this:
if (options.OpenCloseOverridesOptions != null && !options.OpenCloseOverridesOptions?.AreEqual(OpenCloseOverridesOptions)
|| !options.DeliveryOpenCloseOverridesOptions?.AreEqual(DeliveryOpenCloseOverridesOptions)
|| !options.PickupOpenCloseOverridesOptions?.AreEqual(PickupOpenCloseOverridesOptions))
return false;
Use the safe-navigation operator that was introduced in C#6 and a single if statement with several conditions, e.g.:
if (options.OpenCloseOverridesOptions?.AreEqual(OpenCloseOverridesOptions) != true
|| options.DeliveryOpenCloseOverridesOptions?.AreEqual(DeliveryOpenCloseOverridesOptions) != true
|| options.PickupOpenCloseOverridesOptions?.AreEqual(PickupOpenCloseOverridesOptions) != true)
return false;

C# if statement with string.Contains() not working as expected

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

Using ternary operator to check if null - null reference is not the same as null

I am attempting to use the ternary operator to check if a value is null and return one expression or the other. What I'm experiencing when incorporating this into a LINQ expression is that the Transact-SQL translation of the LINQ expression attempts to do a "column = null" rather than a "column IS NULL". I have reason to believe that this is because I'm doing the following:
mappedColumnName == (myVar == null ? null : myOtherVar)
Since it translates the following to columnName IS NULL in Transact-SQL:
mappedColumnName == null
Does anyone have any experience with this? I'd very much like to get this to work.
The entire LINQ expression:
(from MenuItem in menuContext.Menus
where MenuItem.IsSysAdmin == (ClientID == 1 ? true : false)
&& MenuItem.IsActive == true
&& MenuItem.ParentMenuCode == (ActiveSubMenu==null?null:ActiveMenu)
&& MenuItem.ClientID == (UseClientMenu ? ClientID : 0)
&& MenuItem.EmployeeID == (UseEmployeeMenu ? EmployeeID : 0)
orderby MenuItem.SortOrder, MenuItem.MenuName
select MenuItem);
Why don't you use
mappedColumnName == (myVar == null ? DBNull.Value: myOtherVar)
instead?
I've never actually attempted to use ternary operators in linq although you could write it as:
(
(myVar == null && mappedColumnName == null ) ||
(myVar != null && mappedColumnNmae == myOtherVar)
)
try this
(from MenuItem in menuContext.Menus
where MenuItem.IsSysAdmin == ((ClientID == 1 )? true : false)
&& MenuItem.IsActive == true
&& MenuItem.ParentMenuCode == ( (ActiveSubMenu==null) ?null:ActiveMenu)
&& MenuItem.ClientID == (UseClientMenu ? ClientID : 0)
&& MenuItem.EmployeeID == (UseEmployeeMenu ? EmployeeID : 0)
orderby MenuItem.SortOrder, MenuItem.MenuName
select MenuItem);

Boolean Or containing Ternary conditional operation doesn't get short-circuited

In general, the short circuit or operator || ignores the right side of the or if the left side evaluates to true. Apparently, we've found an exception to this.
Check out the following:
if (foo == null || bar != true ? foo.Count == 0 : true)
{
}
This code throws a null reference exception on the command foo.Count because foo is null. And naturally, the boolean logic allows for this. But, if foo is null you would expect that the or would short circuit and not even evaluate the right side of the expression, but it still does, and it throws an exception.
Is this a bug in my code or in the C# compiler? Is there a part of the C# specification that handles this case?
That's because your statement isn't being evaluated as you expect.
You need some extra parenthesis:
if(foo == null || (bar != true ? foo.Count == 0 : true))
The way it's written now is equivalent to (due to operator precedence):
if((foo == null || bar != true) ? foo.Count == 0 : true)
No, it works correctly, refer to operator precedence. || will be evaluated before ?:
So it firstly evaluates foo == null || bar != true and then ? foo.Count == 0 : true, so it's more like:
if ((foo == null || bar != true) ? foo.Count == 0 : true)
{
}
If you want to use short-circut here then it should be:
if (foo == null || (bar != true ? foo.Count == 0 : true))
{
}
Imagine parentheses around the condition you're checking:
if ((foo == null || bar != true) ? foo.Count == 0 : true)
{
}
Thus, if foo is null, you're attempting to read foo.Count, which will naturally result in a NullReferenceException.
According to Operator precedence and associativity conditional operator ?: has lowest priority. Thus it will be executed last. Like this:
(foo == null || bar != true) ? foo.Count == 0 : true

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