I want a conditional dot operator
27 Jul 2011This post was imported from blogspot.
I was writing earlier about features I'd like to have in the .NET Framework and C#, but I forgot a couple. Earlier I wrote about the "slide operator". Now, I'd like to propose the conditional dot or "null dot" operator.Some people will say this idea makes the language too complex, but I can't seem to get enough language features. I use just about all of C#'s existing features, including the "hidden" ones. And still I can think of many unsupported features that I know would improve productivity, code clarity, or performance... at least for me.
I think it's okay for C# to have tons of features, but the IDE needs to help teach people what they mean. For example, Visual Studio should show the name of an operator in a tooltip when mousing over it, and show a help page for it if the user puts the cursor on it and presses F1.
C# already has a handy "??" operator which lets you choose a default value in case the "first choice" is null:
Console.WriteLine("Your name is {0}.", firstName ?? "(unknown)");I use this feature somewhat often. But something's missing. I would like, in addition, a "conditional dot" operator, another kind of null guard that deals with cases where an object you want to access might be null. For example, let's say your class has a reference to another class, and you'd like to inform it when something happened:
if (referenceToAnotherClass != null)
referenceToAnotherClass.OnSomethingHappened(info);
Of course you can't call the method if the referenceToAnotherClass is null. It would be nice if we could shorten this to something likereferenceToAnotherClass??.OnSomethingHappened(info);
If the method you want to call returns a value, the "??." operator would substitute null for the return value if the class reference is null. For example,
// firstName might be null; length will be null if firstName is null.
int? length = firstName??.Length;
It would be very natural to combine the "??." operator with the existing "??" operator:// Equivalent to firstName != null ? firstName.Length : 0
int length = firstName??.Length ?? 0;
This operator would be most powerful when it is chained together, or used to avoid creating temporary variables:// If "DatabaseConnection", "PersonTable", and "FirstRow" can all
// return null, chaining "??." simplifies your code a lot.
var firstName = DatabaseConnection??.Tables.PersonTable??.FirstRow??.Name;
// Equivalent to:
string firstName = null;
var dbc = DatabaseConnection;
if (dbc != null) {
var pt = dbc.Tables.PersonTable;
if (pt != null) {
var fr = pt.FirstRow;
if (fr != null)
firstName = fr.Name;
}
}
The operator should also help invoke events:
public event EventHandler Click;
protected void OnClick()
{
Click??.(this, EventArgs.Empty);
// equivalent to:
if (Click != null)
Click(this, EventArgs.Empty);
// Note: the dot in "??." is still required because "X??(Y)"
// would be indistinguishable from the null coalescing operator.
}
Somebody implemented a "null dot" extension method that provides this kind of "operator" in C#, except that it only supports one out of the four cases I just described, as it requires that the function you want to call return a reference type; it doesn't support void or struct return values. It's also slightly clumsy, and since it relies on a lambda, it hurts performance. To work well, this feature needs language support.Right now I am working with code that often converts objects to strings (the objects are usually strings, but may be something else). The object is sometimes null, so I write
string s = (obj ?? "").ToString();
This works fine, but it's less efficient than it could be, because if obj == null, a virtual call to ToString() will be called on the empty string "". If the "null dot" or "conditional dot" operator existed, I would write this code asstring s = obj??.ToString() ?? "";
or evenstring s = obj??.ToString();
if a null result is acceptable.I know that an operator like this exists in some other languages, but I don't which ones at the moment. Anybody remember?
P.S. Microsoft somehow forgot to include a compound assignment operator, which should work like the other compound assignment operators.
twosies += 2; // equivalent to twosies = twosies + 2
doubled *= 2; // equivalent to doubled = doubled * 2
// ensure myList is not null
myList ??= new List<int>(); // myList = myList ?? new List<int>()