将null合并运算符与条件运算符组合



我正在尝试将合并运算符与条件运算符相结合。这不会编译,我想知道是否有一种方法可以绕过它而不写一堆if语句:

public static Setting GetSetting(this Account account, string key, bool newIfNull = true)
{
return account.Settings
.FirstOrDefault(x =>
x.Key.Equals(key, StringComparison.CurrentCultureIgnoreCase)) ??
newIfNull ? new Setting
{
Key = key
} : null
};
}

这将是if statments:的替代方案

public static Setting GetSetting(this Account account, string key, bool newIfNull = true)
{
var setting = account.Settings
.FirstOrDefault(x =>
x.Key.Equals(key, StringComparison.CurrentCultureIgnoreCase));
if (setting != null)
{
return setting;
}
return newIfNull ? new Setting
{
Key = key
} : null;
}

有什么建议吗?我也很好奇,如果有人知道的话,为什么它不能编译。

空合并运算符比三元运算符具有更高的先验性。这意味着表达式:

thing ?? cond ? t : f

获取绑定为:

(thing ?? cond) ? t : f

如果你想改变这一点,请使用与解决每个优先级问题相同的工具:括号。

thing ?? (cond ? t : f)

在您的示例中:

public static Setting GetSetting(this Account account, string key, bool newIfNull = true)
{
return account.Settings
.FirstOrDefault(x =>
x.Key.Equals(key, StringComparison.CurrentCultureIgnoreCase)) ??
(newIfNull ? new Setting
{
Key = key
} : null)
};
}

开关表达式更容易阅读:

var setting = account.Settings
.FirstOrDefault(x =>x.Key.Equals(key, StringComparison.CurrentCultureIgnoreCase));
return setting switch {
Setting s=>s,
null when newIfNull =>new Setting { Key = key },
_ => null
};

var setting = account.Settings
.FirstOrDefault(x =>x.Key.Equals(key, StringComparison.CurrentCultureIgnoreCase));
return (setting,newIfNull) 
switch 
{
(Setting s,_)=>s,
(_,true)  => new Setting { Key = key },
_ => null
};

这可以用一个单独的表达式来表达,但我怀疑这个问题本身就表明一句话并不总是一个好主意:

return account.Settings
.FirstOrDefault(x =>x.Key.Equals(key, StringComparison.CurrentCultureIgnoreCase))
switch {
Setting s=>s,
null when newIfNull =>new Setting { Key = key },
_ => null
};

出于学术目的,元组形式是

return ( newIfNull, account.Settings.FirstOrDefault(x =>x.Key.Equals(key, 
StringComparison.CurrentCultureIgnoreCase))
)
switch 
{
(_,Setting s)=>s,
(true,_)  => new Setting { Key = key },
_ => null
};

最新更新