Skip to content

Instantly share code, notes, and snippets.

@Ariex
Created June 9, 2016 06:54
Show Gist options
  • Save Ariex/50df00e227feaeb6bb8f09d1c785b133 to your computer and use it in GitHub Desktop.
Save Ariex/50df00e227feaeb6bb8f09d1c785b133 to your computer and use it in GitHub Desktop.
/// <summary>
/// Evaluates the arguments in order and returns the current value of the first expression that initially does not evaluate to NULL.
/// </summary>
/// <typeparam name="T">Target Type, has to be a class type</typeparam>
/// <param name="validator">An evaluation method, check if current alternative is valid as a return value.</param>
/// <param name="that">The first alternative value</param>
/// <param name="alternatives">Alternatives could be a value that is or can convert to target type; or a Func that return value as target type.</param>
/// <returns>The first value that is not null (or white spaces for string) in arguments.</returns>
public static T Coalesce<T>(this T that, Func<T, bool> validator, params object[] alternatives) where T : class
{
validator = validator ?? new Func<T, bool>(v => v != null && (v is string && !string.IsNullOrWhiteSpace(v as string)));
// return the first value when it is not null or white spaces for string
if (validator(that))
{
return that;
}
T res = null;
object[] alts = null;
// if there is no alternatives, then return null
if (alternatives == null || alternatives.Length < 1)
{
return null;
}
else
{
// grab first alternative
var r = alternatives.First();
if (r is Func<T>)
{
// execute the function
try
{
res = (r as Func<T>)();
}
catch {
// don't care if exception happened, just go next
}
}
else
{
res = r as T;
}
// update alternatives
alts = alternatives.Skip(1).ToArray();
}
return res.Coalesce(validator, alts);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment