Possible pitfalls of using this (extension method based) shorthand

.net, c#, extension-methods

Solution

We independently came up with the exact same extension method name and implementation: Null-propagating extension method. So we don't think it's confusing or an abuse of extension methods.

I would write your "multiple levels" example with chaining as follows:

propertyValue1 = myObject.IfNotNull(o => o.ObjectProp).IfNotNull(p => p.StringProperty);

There's a now-closed bug on Microsoft Connect that proposed "?." as a new C# operator that would perform this null propagation. Mads Torgersen (from the C# language team) briefly explained why they won't implement it.

Problem

C#6 Update In C#6 `?.` is now a language feature: ``` // C#1-5 propertyValue1 = myObject != null ? myObject.StringProperty : null; // C#6 propertyValue1 = myObject?.StringProperty; ``` The question below still applies to older versions, but if developing a new application using the new `?.` operator is far better practice. Original Question: I regularly want to access properties on possibly null objects: ``` string propertyValue1 = null; if( myObject1 != null ) propertyValue1 = myObject1.StringProperty; int propertyValue2 = 0; if( myObject2 != null ) propertyValue2 = myObject2.IntProperty; ``` And so on... I use this so often that I have a snippet for it. You can shorten this to some extent with an inline if: ``` propertyValue1 = myObject != null ? myObject.StringProperty : null; ``` However this is a little clunky, especially if setting lots of properties or if more than one level can be null, for instance: ``` propertyValue1 = myObject != null ? (myObject.ObjectProp != null ? myObject.ObjectProp.StringProperty) : null : null; ``` What I really want is `??` style syntax, which works great for directly null types: ``` int? i = SomeFunctionWhichMightReturnNull(); propertyValue2 = i ?? 0; ``` So I came up with the following: ``` public static TResult IfNotNull<T, TResult>( this T input, Func<T, TResult> action, TResult valueIfNull ) where T : class { if ( input != null ) return action( input ); else return valueIfNull; } //lets us have a null default if the type is nullable public static TResult IfNotNull<T, TResult>( this T input, Func<T, TResult> action ) where T : class where TResult : class { return input.IfNotNull( action, null ); } ``` This lets me us this syntax: ``` propertyValue1 = myObject1.IfNotNull( x => x.StringProperty ); propertyValue2 = myObject2.IfNotNull( x => x.IntProperty, 0); //or one with multiple levels propertyValue1 = myObject.IfNotNull( o => o.ObjectProp.IfNotNull( p => p.StringProperty ) ); ``` This simplifies these calls, but I'm not sure about checking this sort of extension method in - it does make the code a little easier to read, but at the cost of extending object. This would appear on everything, although I could put it in a specifically referenced namespace. This example is a rather simple one, a slightly more complex one would be comparing two nullable object properties: ``` if( ( obj1 == null && obj2 == null ) || ( obj1 != null && obj2 != null && obj1.Property == obj2.Property ) ) ... //becomes if( obj1.NullCompare( obj2, (x,y) => x.Property == y.Property ) ... ``` What are the pitfalls of using extensions in this way? Are other coders likely to be confused? Is this just abuse of extensions? I guess what I really want here is a compiler/language extension: ``` propertyValue1 = myObject != null ? myObject.StringProperty : null; //becomes propertyValue1 = myObject?StringProperty; ``` This would make the complex case far easier: ``` propertyValue1 = myObject != null ? (myObject.ObjectProp != null ? myObject.ObjectProp.StringProperty) : null //becomes propertyValue1 = myObject?ObjectProp?StringProperty; ``` This would only work for value types, but you could return nullable equivalents: ``` int? propertyValue2 = myObject?ObjectProp?IntProperty; //or int propertyValue3 = myObject?ObjectProp?IntProperty ?? 0; ```

Original source