Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Chaining the C# ?? Operator


:P
On this page:

C# 2.0 has a nice ?? operator that works as a shortcut for:

string value1 = null;
string value2 = "Test1";
string result = value1 != null ? value1 : value2;    

which causes result containing Test1 or the second value.

In C# you can shortcut this special null comparison case with the new ??:

string result = value1 ?? value2;

which is a little easier to write. This is probably not news to you, but what's really useful is that you can chain these operators together so you can do a whole bunch of null comparisons in a single stroke. For example, I frequently look for a few different querystring variables in a page:

string partner = Request.QueryString["GoogleId"] ?? 
Request.QueryString["PartnerId"] ??
Request.QueryString["UserKey"] ??
                 string.Empty;

which still yields a valid result for the first non-null querystring or if nothing is found returning "".

Note that this also works with the longhand syntax in the first example if you use brackets, but more than one level gets pretty unreadable quickly. The ?? syntax on the other is easily readable. This can certainly save you from writing a bunch of nested IF statements to check for multiple conditions.

Reminds me a bit of JavaScript code using || syntax for null checking, and maybe that's why I just ran into the chaining aspect now <g>...

Posted in CSharp  

The Voices of Reason


 

Chris
January 23, 2008

# re: Chaining the C# ?? Operator

That's a nice illustration.

In practice though, a Request.QueryString["key"] should be checked using a method like IsNullOrEmpty:

bool IsNullOrEmpty(string s)
{
if (s == null || s == string.Empty || s.Trim() == string.Empty)
return false;
return true;
}

Cool example.

John S.
January 23, 2008

# re: Chaining the C# ?? Operator

Chris,
Why write your own IsNullOrEmpty when string.IsNullOrEmpty exists? Granted, it doesn't automatically trim the string but string.IsNullOrEmpty(s.Trim()); would get you the same result.

Rick,
Nice method. I've been trying to use similar techniques to make my validation routines more readable. I'd kill for a &&= operator so that this:

bool isValid = true;
isValid = isValid && (obj != null);
isValid = isValid && (obj.IsLoaded);


Could become:
bool isValid = true;
isValid &&= (obj != null);
isValid &&= (obj.IsLoaded);


That way once isValid went false the second half of the expression wouldn't be evaluated. &= exists but its not short-circuited like &&.

Rick Strahl
January 23, 2008

# re: Chaining the C# ?? Operator

@Chris - in theory yes - you should check for empty too but how often do you have an empty querystring value? QueryString[] will return null if the key doesn't exist. In the case above there would never be an empty string for a querystring value (because I'm providing the partner URL <g>).

Nate
January 24, 2008

# re: Chaining the C# ?? Operator

Nice post; I had no idea. Reminds me of the SQL COALESCE function.

Josh Stodola
January 24, 2008

# re: Chaining the C# ?? Operator

Cool, I like this. Now, how can I do it in VB?!

sebastien crocquesel
January 24, 2008

# re: Chaining the C# ?? Operator

That's why this operator is called coalesce operator. Like in SQL, when chained it returns the first non null value.

And btw, (s.Length == 0) is far more faster than (s == string.Empty) and it is how IsNullOrEmpty was coded by MS.

Dejan
January 24, 2008

# re: Chaining the C# ?? Operator

>> Why write your own IsNullOrEmpty when string.IsNullOrEmpty exists?
>> Granted, it doesn't automatically trim the string but
>> string.IsNullOrEmpty(s.Trim()); would get you the same result.

No.

If you did something like:

string s = null;
bool b = string.IsNullOrEmpty(s.Trim());

You'd get argument null exception (because s *is* null).
In the above post short-circuit (e.g. || and not |) operator is used, so first thing that gets checked is null reference and everything is OK.

Personally, I like to declare extension method:

public static bool IsEmpty(this string s)
{
return s == null || s.Length == 0 || s.Trim().Length == 0;
}

This way, example works OK.

string s = null;
bool b = s.IsEmpty();

LP,
Dejan

Rick Strahl
January 24, 2008

# re: Chaining the C# ?? Operator

Isn't that obvious? Of course you can't compare for null of an expression that requires a reference in the first place.

Most people would consider a padded string not empty because if you have one most likely there's a reason for it.

Bart Czernicki
January 25, 2008

# re: Chaining the C# ?? Operator

Another reason to write your own "IsEmpty" type operation for strings is because there is a bug when checking IsNullEmpty in .NET 2.0 in a for loop. Not sure if 3.5 fixes this. Something I actually ran into several months ago.

Rick,

I actually use the "question mark" questions when we are interviewing sr. developers at my job. Ternary operator (?), null coalescing (??) and nullable types (int?). It gives a nice theme to the interview. But to add to you post, the ternary operator and null coalescing are pretty powerful..because of the brevity they provide when chaining multiple "if type" statements.

Alois Kraus
January 27, 2008

# re: Chaining the C# ?? Operator

I have proposed a similar syntax extension

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=306293

This would make it possible to change this:

string currentValue = String.Empty;
if (AppSettings != null && AppSettings[Key] != null)
{
currentValue = AppSettings[Key].Value ?? String.Empty;
}

to
string currentValue = AppSettings?.GetElementKey(Key)?.Value ?? String.Empty;

Yours,
Alois Kraus

Tigraine
January 29, 2008

# re: Chaining the C# ?? Operator

I would also disagree with the usage for QueryStrings.
There are methods like string.IsNullOrEmpty but furthermore you show off some IDs that need to be parsed.

So i usually prefer to parse them through int.TryParse

int result;
if (!int.TryParse(Request.QueryString["SomeId"], Result))
{
        throw new Exception("Not parseable");
}


But I agree, the ?? operator is quite powerful indeed, you just didn't pick the right example.

greetings Daniel

leppie
January 29, 2008

John S.
January 29, 2008

# re: Chaining the C# ?? Operator

"there is a bug when checking IsNullEmpty in .NET 2.0 in a for loop. Not sure if 3.5 fixes this"

Fixed in 2.0 SP1 (and 3.5): http://support.microsoft.com/kb/945757

Nicolas Zapata
March 21, 2008

# re: Chaining the C# ?? Operator

There´s a annoying problem with the ?? and thats when you try something like this for example:

public void InsertStringIntoDataRow(string element, DataRow row)
{
row["something"] = element ?? DBNull.value;
}

you get a compilation error because of the difference in types....A shame :(

Saajid
April 23, 2008

# re: Chaining the C# ?? Operator

Nicolas, in response to your code snippet below:

public void InsertStringIntoDataRow(string element, DataRow row)
{
row["something"] = element ?? DBNull.value;
}



I'f i'm not mistaken, all you have to do is cast one or both of the arguments to object. This should work since your are using an untyped DataRow object. This should except arguments of type object. I've done this before when using the ternary ?: operator to add SqlParameters to a SqlParameterCollection, as follows:

SqlParameterCollection params = new SqlParameterCollection ();
params.AddWithValue("@ParentNamespaceID", nmRow.IsParentNamespace_IDNull() ? DBNull.Value : (object)nmRow.ParentNamespace_ID);

Tristan
July 06, 2008

# re: Chaining the C# ?? Operator

John S, the operator does exist, just with a single ampersand:
x &= y;

is equivalent to
x = x & y;

except that x is only evaluated once. The & operator performs a bitwise logical AND operation on integral operands and logical AND on bool operands.

Pete Hurst
August 04, 2008

# re: Chaining the C# ?? Operator

So, seems I'm not the only one who wrote an IsEmpty() extension :)

Which do you think looks better? (And is more OO)

String.IsNullOrEmpty(myString)

or

myString.IsEmpty()

In a way, this has better functionality as an extension than if it were implemented directly on the String class, because obviously you can't call an instance method if the instance is null :)

I still think PHP / Javascript have it better...

if ($myString) {
// string isn't empty!
}

I wonder if an implicit cast to bool would be possible on a string?

Nathan
February 22, 2009

# re: Chaining the C# ?? Operator

On the topic of IsNullOrEmpty and extension methods, here's my spin on it that allows you to specify a default/alternate value:

/// <summary>
/// Tests whether a tring is null or empty, and if so returns the
/// alternate instead of the source value.
/// </summary>
/// <param name="str">The source string</param>
/// <param name="alternateValue">The alternate value</param>
/// <returns>A string</returns>
public static string IfNullOrEmpty(this string str, string alternateValue)
{
if (str == null || str.Length == 0 || str.Trim().Length == 0)
{
return alternateValue;
}
return str;
}

Example Usage:

string someVar = Request.QueryString["someID"].IfNullOrEmpty("SomeDefaultValue");

VistaDB.Net Blog
May 18, 2009

# 3.3 API Changes and more - Nullable is not null?

3.3 API Changes and more - Nullable is not null?

Developer
March 15, 2010

# re: Chaining the C# ?? Operator

Try the following

public static class Validator
{
public static T IsNull<T>(object value, T defaultValue)
{
return ((Object.Equals(value, null)) | (object.Equals(value, DBNull.Value)) ? (T)defaultValue : (T)value);
}

public static T IsNull<T>(object value)
{
return IsNull<T>(value, default(T));
}
}

Erik A. Brandstadmoen
September 01, 2010

# re: Chaining the C# ?? Operator

As a comment to the IsNullOrEmpty discussion: .NET 4.0 introduces the IsNullOrWhiteSpace method on strings:

IsNullOrWhiteSpace is a convenience method that is similar to the following code, except that it offers superior performance:

return String.IsNullOrEmpty(value) || value.Trim().Length == 0;

http://msdn.microsoft.com/en-us/library/system.string.isnullorwhitespace.aspx

:)

Darren.R
February 05, 2012

# re: Chaining the C# ?? Operator

Alternative

s + "" != ""

nice way to do it.

john H
November 30, 2016

# re: Chaining the C# ?? Operator

Cool, I like this. Now, how can I do it in VB?!

change to c# vb.net was never supposed to be released


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024