In my travels around .Net land, I've come to know, love and exploit several denizens of the tribe of C#. Some of these have already been written about, such as Yield return and the => operator. But more recently, I've had the opportunity to educate some fellow travelers on two of the most useful, but least used operator. Those being the Comparison Operator (?:) and the Null Coalescing Operator (??).
Lets start our adventure by watching the Comparison Operator in it's natural environment. If you watch closely, it'll show you it's syntax...
bool statement ? true : false
Due to it's nature, this operator is sometimes called the Ternary operator. The reason being is that it takes 3 operands. In normal use, here is what it looks like:
CurrentBeer.Empty==True ? CurrentBeer = Wife.GetMebeer() : Me.TakeDrink(CurrentBeer);
(this can be shortened further by taking out the ==True, since .Empty is most likely a bool property)
CurrentBeer.Empty?CurrentBeer=Wife.GetMeBeer():Me.TakeDrink(CurrentBeer);
You can see how this replaces the overly verbose syntax of :
If(CurrentBeer.Empty)
CurrentBeer = Wife.GetMeBeer();
else
Me.TakeDrink(CurrentBeer);
Syntax sugar? Maybe. But it's definitely useful as a quick way to get things done. Elegant, Efficient and Desirable, three features my first girlfriend was lacking in.
But wait! Theres more! Just send me three easy payments of $29.95!
So now, lets check out the ?? operator.
The ?? operator has saved me boat loads of finger_impact_on_keyboard stress ever since the advent of C# 2.0. It's easiest to think of this operator working similar to the comparison operator above. Lets lift it's skirt real quick and have a peek at how it functions
x = ValueThatMightBeNull ?? DifferentValue;
Ok, much like the first time you played doctor, things might be confusing, but it's really simple. Basically the ?? will evaluate whether or not the thing to the left of it is null, if it is, it will evaluate and return the thing on the right. Lets just see it in action, it's easier that way...<Dear "Usually offended by my posts": Please Insert vulgar joke of your choice here>
//This is how my wife found me
Mate SuitableMate = Mate.Get(GoodLooking)??
Mate.Get(AverageLooking)??
Mate.Get(DoesntHaveAnAssForAFace)??
Mate.Get(AtleastHeHasAJob)??
Mate.Get(Dave)
If your confused, let me lighten things up for you hear. Each A = B??C statement is the equivalent of saying
If(B != null)
A = B;
else
A = C;
So when we string them together like that, it's just like saying If = null else if = null else if = null etc etc etc... So, obviously, based on our previous statement, everything up to Mate.Get(Dave) must have returned null if my wife wound up with me. I do have a job now though....so I wonder if i still would have made the cut.
There is one more benefit of using the ?? operator that I actually stumbled across. Take this code as an example:
public class DataObject
{
public NullableObject a = 1... etc
}
public class BO
{
public NullableObject Stinks= 0;
public static implicit operator BO(DataObject e)
{
return new DataObject{Stinks= e.a};
}
}
now...later on in the UI of the app (which should NOT have ANY reference to the DataObject class) if we write this code:
If(MyBo==null){Console.WriteLine("WOO HOO, You have no BO!!");}
..were going to get a compiler error. The reason being, as far as I understand (hopefully commenter's can expand on this) is that when you compile that statement, the compiler is doing type checking against the objects used in the class your checking for null in. In other words it checks to see if anything is returning null from within the class. Now, since the operator takes a type of DataObject, the complier expect you to have a reference to that class...if you don't, then *Poof* no compile.
Now, to get around this, we can write...
SomeoneElsesBo = MyBo??(MyBo = new BO());
....And the compiler is happy.
Hell, we can even put these two operators together, check this out:
Mate SuitableMate;
Step Next_Step_In_Life = ((SuitableMate = Mate.Get(GoodLooking)??
Mate.Get(AverageLooking)??
Mate.Get(DoesntHaveAnAssForAFace)??
Mate.Get(AtleastHeHasAJob)??
Mate.Get(Dave)) == Dave?SobQuietly():null)??(Step)PartyItUpWOOT();
I'll leave you with this. The best places I've found to use the ?? operator is in returning data base fields where the value might be null, here is a quick example and the best way I've found to implement the ?? solution
//First i check to see if the value from the db is DBNull.value
//Dr = DataReader
//Do = Data Object with nullable Types
DO.ValX == DBNull.Value?null:(Int32?)dr[0]
//If you don't get the ? reference after the Int32, no worries, It's a nullable type, and I'll post about it soon.
The reason I do this, is so I can keep the actual DB value in my DataObject, which is supposed to be a true reflection of my data. Later on, in the actual business object, where I don't accept Nullable types I can say this.
BO.ActualValX = DO.ValX??-1;
And Bada-Bing, I'm good to go. Later on, i can pass either -1 or even null back into the DB and repeat this cycle when retrieving my data, it works, and i don't have any logic, other than conversions from DBNull, in my Data Object class.