Why Does One Often See "Null != Variable" Instead of "Variable != Null" in C#

Why does one often see null != variable instead of variable != null in C#?

It's a hold-over from C. In C, if you either use a bad compiler or don't have warnings turned up high enough, this will compile with no warning whatsoever (and is indeed legal code):

// Probably wrong
if (x = 5)

when you actually probably meant

if (x == 5)

You can work around this in C by doing:

if (5 == x)

A typo here will result in invalid code.

Now, in C# this is all piffle. Unless you're comparing two Boolean values (which is rare, IME) you can write the more readable code, as an "if" statement requires a Boolean expression to start with, and the type of "x=5" is Int32, not Boolean.

I suggest that if you see this in your colleagues' code, you educate them in the ways of modern languages, and suggest they write the more natural form in future.

Why null == myVar instead of myVar == null?

It's an old habit to avoid the accidental typo of myVar = null (whoops). It's still helpful in some languages, but C# will protect you from doing it, so it's not necessary there.

if(value == null) vs if(null == value)

I doubt that there's a measurable performance advantage either way. I'll bet the person who told you this didn't have any hard data.

As far as I know, it's a historical artifact, a technique from C and C++ to guard against this mistake:

if (c = null) {
}

The compiler will catch this if you reverse the arguments, since you can't assign something to null.

(0 == variable) or (null == obj): An outdated practice in C#?

No, there's no need for this, because the problem it tries to avoid - namely the typo of:

if (variable = 0)

wouldn't compile in C# anyway. The conditions in if statements have to be Boolean. There's still a risk of making one of these mistakes:

if (something = true)
if (something = false)

if something is a Boolean variable, but the better way to fix this is to avoid the constant:

if (something)
if (!something)

If you have developers bringing over idioms like this from other languages without thinking about whether they're appropriate in C#, you should keep an eye for them doing more of the same. If you try to write C# as if it's C++ (or any other language, pretty much - with the possible exception of VB.NET) you'll end up writing non-idiomatic C# code.

EDIT: As cletus noted, there is another potential area for concern:

bool a = false, b = true; 
if (a = b) { } // No warnings

So the error can still occur - but then we're outside the realm of comparing with a constant anyway :) I'd say this crops up incredibly rarely, and isn't worth too much time spent worrying about it.

Null variable issues errors while trying to repurpose a bot

Remove the declaration of local entirely. It's never used for anything, so spending any time determining its type is wasted.

The __Null type was likely inserted simply to obfuscate the code and hinder any attempts to decompile the code.

Replace any instances of local with null, as in:

DateTime.ParseExact(s1, "HH:mm", (IFormatProvider) local);
↓ ↓
DateTime.ParseExact(s1, "HH:mm", (IFormatProvider) null);

check for null variables

I, personally, would have separate checks for each variable. On "error message" for multiple validation checks is a bad idea.

The main reason for this is that your "error message" should likely be an ArgumentNullException, which should provide the proper parameter name. This will be different per variable. Even if you use a custom exception, providing information about which variable was improperly specified is worth the extra coding effort.

That being said, if you want to do this, you can use:

var Var1 = blah1;
var Var2 = blah2;
var Var3 = blah3;
var Var4 = blah4;
var Var5 = blah5;

if ( (new object[] {Var1, Var2, Var3, Var4, Var5}).Any(v => v==null))
throw new Exception("Your error here");

Why is my element variable always null in this foreach loop?

I'm going to guess that u is not null in itself, but one of it's properties is null, or the Roles.GetRolesForUser(u.UserName) call returns null. If that is the case then when you try to access the members of those null values you get the NullReferenceException.

Example:

public class Person
{
public Address HomeAddress { get; set; }
}

public class Address
{
public String StreetAddress { get; set; }
}

public void SomeFunc()
{
var person = new Person();

//NullReferenceException because HomeAddress is null.
//NOT because person is null...
var address = person.HomeAddress.StreetAddress;
}

You can verify this by hovering over each item in the Debugger to ensure that it is not null, but I bet you one of those objects is. To ensure that your GetRolesForUser method is not returning null, simply call that in the immediate window and see what you get back. If you get back null, there's your issue.

Alternatively, just throw each of the right hand assignments into your local watch window and one of them will present itself as the issue.


Oh, and a few other things...

  1. If you are planning to return an IEnumerable<T> do not create a list and then return that list, instead just yield return your objects.

  2. Use null coalescing operators when necessary.

  3. Use a using statement for your IDisposable objects.

Fixed version:

public IEnumerable<UserSummary> getUserSummaryList()
{
using (var db = new EntityContext())
{
foreach (aspnet_Users user in users)
{
// Retrieve the username (with logic if it is null or empty)
var username = user.UserName;

// Retrieve the email (with logic if it is null or empty)
var email = (user.aspnet_Membership != null)
? user.aspnet_Membership.Email ?? String.Empty
: String.Empty;

// Retrieve the role (with logic if it is null)
var roles = Roles.GetRolesForUser(username);
var role = (roles != null) ? roles.FirstOrDefault() : null;

// Retrieve the Ad Company (with logic if it is null)
var adCompany = (user.AD_COMPANIES != null)
? user.AD_COMPANIES.ad_company_name ?? "Not an Advertiser"
: "Not an Advertiser";

var empName = (user.EMPLOYEE != null)
? user.EMPLOYEE.emp_name ?? "Not an Employee"
: "Not an Employee";

yield return new UserSummary
{
UserName = username,
Email = email,
Role = role,
AdCompany = adCompany,
EmployeeName = empName,
};
}
}
}

Can a nullable variable in C# be marked as non-null from some point on for the compiler?

It looks like you just want to allow the method to be called without specifying a parameter (and use a certain default in that case).

There is another possible solution to this particular scenario:. Just overload f() like so:

static void f()
{
f(new A { x = 3 });
}

static void f(A a)
{
Console.WriteLine(a.x);
}

Code can then call f() with or without a parameter, but the difference is that in the case where it calls f(A a) with a parameter, it cannot be null.


(In response to your comment below.)

If you want to handle being able to call with a possibly-null struct, you can overload like this instead:

static void f(A? a = default)
{
f(a ?? new A { x = 3 });
}

static void f(A a)
{
Console.WriteLine(a.x);
}

That means your implementation doesn't have to deal with a possibly-null value, but you can still omit the argument at the call site, or call it with a null value.

Note: You can simplify static void f(A? a = default) to:

static void f(A? a = default) => f(a ?? new A { x = 3 });

if you prefer the shorter syntax.



Related Topics



Leave a reply



Submit