Anne Anne -4 years ago 79
C# Question

Is there a way I can remove the need for a null check in a C# if that later checks for a != ""?

I tried some different combinations but this was the only combination I could get to work as the comparison != "" seemed to give a problem for a null:

if (options.English != null && options.English != "")
if (options.English.StartsWith("^"))
query = query.Where(w => w.English.StartsWith(options.English.Trim().Substring(1)));
query = query.Where(w => w.English.Contains(options.English.Trim()));

Is there any way that I could optimize this to simplify it down to just one if statement or even two if statements that follow each other rather than have an outer and an inner if statement.

Answer Source

If all you're trying to do is remove the nested ifs, then you can store the lambdas in a Dictionary

var lookup = new Dictionary<bool, Func<Options, bool>>() {
    { true, w => w.English.StartsWith(options.English.Trim().Substring(1)) },
    { false, w => w.English.Contains(options.English.Trim())} };

if (options.English != null && options.English != "")
    query = query.Where(lookup[options.English.StartsWith("^")]);

Now, by using String.IsNullOrEmpty() together with ?: you can indeed get this down to one statement...and it's not even horrid:

query = String.IsNullOrEmpty(options.English) ?
    query : query.Where(lookup[options.English.StartsWith("^")]);

But, given that you've got only two options, a Dictionary isn't really needed, just use a few locals:

Func<Options, bool> startsWithCaret = w => w.English.StartsWith(options.English.Trim().Substring(1));
Func<Options, bool> doesNotStartWithCaret = w => w.English.Contains(options.English.Trim());
var lambda = options.English.StartsWith("^") ? startsWithCaret : doesNotStartWithCaret;

You're statement is now

query = String.IsNullOrEmpty(options.English) ? query : query.Where(lambda);

Not an if to be found! :-)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download