Skip to main content

C# extension method to coalesce object (of T) values, or return the first non-null value from a set of specified parameters.

namespace Extensions
{
    public static class ObjectExtensions
    {
        /// <summary>
        /// A T extension method that returns the first non-null value
        /// (including the value of current instance), or the specified default value.
        /// </summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="self">The instance to act on.</param>
        /// <param name="values">A variable-length parameters list containing values.</param>
        /// <returns>The first not null value or a default value.</returns>
        /// <remarks>Original from https://github.com/zzzprojects/Z.ExtensionMethods/blob/master/src/Z.Core/System.Object/Utility/Object.CoalesceOrDefault.cs</remarks>
        public static T CoalesceOrDefault<T>(this T self, params T[] values) where T : class
        {
            if (self != null)
                return self;

            for (var index = 0; index < values.Length; index++)
            {
                var value = values[index];
                if (value != null)
                    return value;
            }

            return default(T);
        }

        /// <summary>
        /// A T extension method that returns the first non-null value (including the value of the current instance).
        /// </summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="self">The instance to act on.</param>
        /// <param name="values">A variable-length parameters list containing values.</param>
        /// <returns>The first non-null value.</returns>
        /// <remarks>Original from https://github.com/zzzprojects/Z.ExtensionMethods/blob/master/src/Z.Core/System.Object/Utility/Object.Coalesce.cs</remarks>
        public static T Coalesce<T>(this T self, params T[] values) where T : class
        {
            if (self != null)
                return self;

            for (var index = 0; index < values.Length; index++)
            {
                var value = values[index];
                if (value != null)
                    return value;
            }

            return null;
        }
    }
}

// ----------------------------------------------------------------------------
// More coalesce examples...
// from: https://github.com/net-commons/common-logging/blob/master/src/Common.Logging.Portable/Logging/Configuration/ArgUtils.cs
// ----------------------------------------------------------------------------

/// <summary>
/// Returns the first non-null, non-empty string value among its arguments.
/// </summary>
/// <remarks>
/// Returns <c>null</c>, if the initial list was null or empty.
/// </remarks>
/// <seealso cref="Coalesce{T}"/>
public static string Coalesce(params string[] values)
{
    return Coalesce(delegate(string v) { return !string.IsNullOrEmpty(v); }, values);
}

/// <summary>
/// Returns the first non-null, non-empty value among its arguments.
/// </summary>
public static T Coalesce<T>(Predicate<T> predicate, params T[] values) where T : class
{
    if (values == null || values.Length == 0)
    {
        return null;
    }

    if (predicate == null)
    {
        predicate = delegate(T v) { return v != null; };
    }

    for (int i = 0; i < values.Length; i++)
    {
        T val = values[i];
        if (predicate(val))
        {
            return val;
        }
    }

    return null;
}