Note that there are some explanatory texts on larger screens.

plurals
  1. POExtending the C# Coalesce Operator
    primarykey
    data
    text
    <p>Before I explain what I want to do, if you look at the following code, would you understand what it's supposed to do? <em>(updated - see below)</em></p> <pre><code>Console.WriteLine( Coalesce.UntilNull(getSomeFoo(), f =&gt; f.Value) ?? "default value"); </code></pre> <p>C# already has a null-coalescing operator that works quite well on simple objects but doesn't help if you need to access a member of that object.</p> <p>E.g.</p> <pre><code>Console.WriteLine(getSomeString()??"default"); </code></pre> <p>works very well but it won't help you here:</p> <pre><code>public class Foo { public Foo(string value) { Value=value; } public string Value { get; private set; } } // this will obviously fail if null was returned Console.WriteLine(getSomeFoo().Value??"default"); // this was the intention Foo foo=getSomeFoo(); Console.WriteLine(foo!=null?foo.Value:"default"); </code></pre> <p>Since this is something that I come across quite often I thought about using an extension method <em>(old version)</em>:</p> <pre><code>public static class Extension { public static TResult Coalesce&lt;T, TResult&gt;(this T obj, Func&lt;T, TResult&gt; func, TResult defaultValue) { if (obj!=null) return func(obj); else return defaultValue; } public static TResult Coalesce&lt;T, TResult&gt;(this T obj, Func&lt;T, TResult&gt; func, Func&lt;TResult&gt; defaultFunc) { if (obj!=null) return func(obj); else return defaultFunc(); } } </code></pre> <p>Which allows me to write:</p> <pre><code>Console.WriteLine(getSomeFoo().Coalesce(f =&gt; f.Value, "default value")); </code></pre> <p>So would you consider this code to be readable? Is Coalesce a good name?</p> <p>Edit 1: removed the brackets as suggested by Marc</p> <h2>Update</h2> <p>I really liked lassevk's suggestions and Groo's feedback. So I added overloads and didn't implement it as an extension method. I also decided that defaultValue was redundant because you could just use the existing ?? operator for that.</p> <p>This is the revised class:</p> <pre><code>public static class Coalesce { public static TResult UntilNull&lt;T, TResult&gt;(T obj, Func&lt;T, TResult&gt; func) where TResult : class { if (obj!=null) return func(obj); else return null; } public static TResult UntilNull&lt;T1, T2, TResult&gt;(T1 obj, Func&lt;T1, T2&gt; func1, Func&lt;T2, TResult&gt; func2) where TResult : class { if (obj!=null) return UntilNull(func1(obj), func2); else return null; } public static TResult UntilNull&lt;T1, T2, T3, TResult&gt;(T1 obj, Func&lt;T1, T2&gt; func1, Func&lt;T2, T3&gt; func2, Func&lt;T3, TResult&gt; func3) where TResult : class { if (obj!=null) return UntilNull(func1(obj), func2, func3); else return null; } public static TResult UntilNull&lt;T1, T2, T3, T4, TResult&gt;(T1 obj, Func&lt;T1, T2&gt; func1, Func&lt;T2, T3&gt; func2, Func&lt;T3, T4&gt; func3, Func&lt;T4, TResult&gt; func4) where TResult : class { if (obj!=null) return UntilNull(func1(obj), func2, func3, func4); else return null; } } </code></pre> <p>Sample usage:</p> <pre><code>Console.WriteLine( Coalesce.UntilNull(getSomeFoo(), f =&gt; f.Value) ?? "default value"); </code></pre> <p>Another sample:</p> <pre><code>public class Bar { public Bar Child { get; set; } public Foo Foo { get; set; } } Bar bar=new Bar { Child=new Bar { Foo=new Foo("value") } }; // prints "value": Console.WriteLine( Coalesce.UntilNull(bar, b =&gt; b.Child, b =&gt; b.Foo, f =&gt; f.Value) ?? "null"); // prints "null": Console.WriteLine( Coalesce.UntilNull(bar, b =&gt; b.Foo, f =&gt; f.Value) ?? "null"); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload