很容易将一些答案转换为具有泛型的辅助扩展类,以实现更广泛的用途:
注意:有关短路方法的说明,请参阅文斯文答案
// classic
public static string Coalesce(this string s, params string[] strings)
=> s.Coalesce(string.IsNullOrEmpty, strings);
// short-circuit compatible, for expensive string getting
public static string Coalesce(this string s, params Func<string>[] getters)
=> s.Coalesce(string.IsNullOrEmpty, getters);
// generic
public static T Coalesce<T>(this T value, Func<T, bool> isEmpty, params T[] values) where T : class
=> isEmpty(value) ? values.FirstOrDefault(val => !isEmpty(val)) : value;
// generic, short-circuit compatible
public static T Coalesce<T>(this T value, Func<T, bool> isEmpty, params Func<T>[] getters) where T : class {
if (isEmpty(value))
return getters
.Select(getter => new Lazy<T>(getter))
.FirstOrDefault(val => !isEmpty(val.Value))
?.Value;
return value;
}
示例用法:
string result = s.SiteNumber.Coalesce(s.AltSiteNumber, "No Number");
string result = s.SiteNumber.Coalesce(string.IsNullOrWhiteSpace, s.AltSiteNumber, "No Number");
string navigationTitle = model?.NavigationTitle.
Coalesce(() => RemoteTitleLookup(model?.ID), () => model?.DisplayName);
Player player = player1.Coalesce(p => p?.Score > 0, player2, player3);
(PS:我想我在这里使用泛型有点跑题了。我想太多了吗?)