Вложенные троичные операторы - PullRequest
3 голосов
/ 18 августа 2011

У меня есть этот код:

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

Есть ли лучший способ написать это, чтобы сделать его более читабельным?

Ответы [ 7 ]

10 голосов
/ 18 августа 2011

В вашем случае вы можете написать вспомогательную функцию, например:

// 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);
6 голосов
/ 18 августа 2011

Напишите отдельный метод для получения номера телефона, примерно так:

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);
3 голосов
/ 21 января 2016

Хотя мне больше всего нравятся ответы Гейба и Владимира. Вот способ заставить вложенные троичные деревья выглядеть расшифрованными.

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

Конечно, так как вы должны заключить их в скобки, это усложняет задачу. В JavaScript это действительно получается очень элегантно, так как допускает вложенные троицы без скобок. Хотя в вашей ситуации этот синтаксис на самом деле не нужен, иногда этот синтаксис очень удобен.

2 голосов
/ 07 июля 2016

Теперь, с помощью LINQ, вы можете сделать его простым и читаемым в одной строке, например

_viewModel.PhoneDefault = user == null ? "" :
(new [] {user.PhoneDay, user.PhoneEvening, user.Mobile}).FirstOrDefault(s => !string.IsNullOrEmpty(s)) ?? "";
1 голос
/ 10 октября 2018

Просто отвечаю, потому что я не видел подход, который я использую в подобных сценариях, ни в одном из существующих ответов.

Как насчет ...

_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, но, тем не менее, я думаю, что это довольно читабельно.

Мои два цента;)

1 голос
/ 18 августа 2011

Ну, пока записи могут быть только нулевыми или действительными:

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

Вы даже можете определить метод расширения для строки, чтобы преобразовать пустые строки в нуль и использовать его здесь, но я просто сумасшедший.

Если они могут быть пустой строкой, просто используйте ответы других людей. Метод Джейсона хорош чистым.

0 голосов
/ 18 августа 2011

Добавление еще нескольких скобок может сделать его более читабельным.Вы также можете разбить его на серию операторов 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 = "";
}
...