嵌套的三元运算符

时间:2011-08-18 07:42:53

标签: c# refactoring ternary-operator

我有这段代码:

_viewModel.PhoneDefault = user == null ? "" :
    (string.IsNullOrEmpty(user.PhoneDay) ?
        (string.IsNullOrEmpty(user.PhoneEvening) ?
            (string.IsNullOrEmpty(user.Mobile) ? "" : 
                user.Mobile) :
            user.PhoneEvening) :
         user.PhoneDay);

有没有更好的方法来编写它以使其更具可读性?

7 个答案:

答案 0 :(得分:10)

在您的情况下,您可以编写一个辅助函数,如下所示:

// return the first parameter that isn't null or empty
public static string CoalesceStrings(params string[] src)
{
    foreach (var str in src)
        if (!string.IsNullOrEmpty(str))
            return str;
    return "";
}

然后就这样打电话:

_viewModel.PhoneDefault = user == null ? "" :
    CoalesceStrings(user.PhoneDay, user.PhoneEvening, user.Mobile);

答案 1 :(得分:6)

写一个单独的方法来获取电话号码,如下所示:

public string GetDefaultPhone(User user)
        {
            if(user == null)
            {
                return string.Empty;
            }

            if(!string.IsNullOrEmpty(user.PhoneDay))
            {
                return user.PhoneDay;
            }

            if(!string.IsNullOrEmpty(user.PhoneEvening))
            {
                return user.PhoneEvening;
            }

            if(!string.IsNullOrEmpty(user.Mobile))
            {
                return user.Mobile;
            }

            return string.Empty;
        }

然后在你的代码中:

_viewModel.PhoneDefault = GetDefaultPhone(user);

答案 2 :(得分:3)

虽然我最喜欢加布和弗拉基米尔的答案。这是一种使嵌套三元看起来难以辨认的方法。

_viewModel.PhoneDefault =
  user == null
    ? ""
  : (string.IsNullOrEmpty(user.PhoneDay)
    ? (string.IsNullOrEmpty(user.PhoneEvening)
      ? (string.IsNullOrEmpty(user.Mobile)
           ? ""
         : user.Mobile)
      : user.PhoneEvening)
    : user.PhoneDay);

当然,因为你必须用括号括起来,所以这样做会更加困难。在JavaScript中它实际上非常优雅,因为它 允许没有括号的嵌套三元组。虽然你的情况并不真的需要这种语法,但有时这种语法非常方便。

答案 3 :(得分:2)

现在,借助LINQ的强大功能,您可以在单行中使其简单易读,如

_viewModel.PhoneDefault = user == null ? "" :
(new [] {user.PhoneDay, user.PhoneEvening, user.Mobile}).FirstOrDefault(s => !string.IsNullOrEmpty(s)) ?? "";

答案 4 :(得分:1)

好吧,只要条目可以为空或有效:

if (user == null)
{
    _viewModel.PhoneDefault = String.Empty;
}
else
{
    _viewModel.PhoneDefault = user.PhoneDay ?? user.PhoneEvening ?? user.Mobile ?? String.Empty;
}

你甚至可以在字符串上定义一个扩展方法,将空字符串转换为null并在此处使用它,但我只是疯了。

如果它们可以是空字符串,只需使用其他人的答案。杰森的方法很干净。

答案 5 :(得分:1)

只需回答,因为在任何现有答案中都没有看到我在这种情况下使用的方法。

那......

_viewModel.PhoneDefault = user == null ? string.Empty :
    !string.IsNullOrEmpty(user.PhoneDay)     ? user.PhoneDay :
    !string.IsNullOrEmpty(user.PhoneEvening) ? user.PhoneEvening :
    !string.IsNullOrEmpty(user.Mobile)       ? user.Mobile : 
    string.Empty;

不便的是,您必须在一开始就按用户的空缺进行检查,因为这会强制重复string.Empty,但是我认为它很可读。

我的两分钱;)

答案 6 :(得分:0)

添加更多括号可能会使其更具可读性。您还可以将其分解为一系列if / else语句

if (user != null)
{
  if (!string.IsNullOrEmpty(user.PhoneDay))
    _viewModel.PhoneDefault = user.PhoneDay;
  else if (!string.IsNullOrEmpty(user.PhoneEvening))
    _viewModel.PhoneDefault = user.PhoneEvening;
  else if (!string.IsNullOrEmpty(user.Mobile))
    _viewModel.PhoneDefault = user.Mobile;
  else
    _viewModel.PhoneDefault = "";
}