可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have this code:
_viewModel.PhoneDefault = user == null ? "" :
(string.IsNullOrEmpty(user.PhoneDay) ?
(string.IsNullOrEmpty(user.PhoneEvening) ?
(string.IsNullOrEmpty(user.Mobile) ? "" :
user.Mobile) :
user.PhoneEvening) :
user.PhoneDay);
Is there a better way to write this to make it more readable?
回答1:
In your case you can write a helper function, like this:
// 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 "";
}
Then just call it, like this:
_viewModel.PhoneDefault = user == null ? "" :
CoalesceStrings(user.PhoneDay, user.PhoneEvening, user.Mobile);
回答2:
Write a seperate method to get the phone number, something like this:
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;
}
And then in your code:
_viewModel.PhoneDefault = GetDefaultPhone(user);
回答3:
Although I like Gabe's and Vladimir's answers the most. Here's a way to make nested ternaries look decipherable.
_viewModel.PhoneDefault =
user == null
? ""
: (string.IsNullOrEmpty(user.PhoneDay)
? (string.IsNullOrEmpty(user.PhoneEvening)
? (string.IsNullOrEmpty(user.Mobile)
? ""
: user.Mobile)
: user.PhoneEvening)
: user.PhoneDay);
Granted, since you have to surround them with parentheses it makes it more difficult to do this. In JavaScript it actually comes out very elegant since it
allows for nested ternaries without the parentheses. Although your situation doesn't really need this syntax sometimes this syntax comes in very handy.
回答4:
Now, with power of LINQ, you can make it simple and readable within single line like
_viewModel.PhoneDefault = user == null ? "" :
(new [] {user.PhoneDay, user.PhoneEvening, user.Mobile}).FirstOrDefault(s => !string.IsNullOrEmpty(s)) ?? "";
回答5:
Well, as long as the entries can be just null or valid:
if (user == null)
{
_viewModel.PhoneDefault = String.Empty;
}
else
{
_viewModel.PhoneDefault = user.PhoneDay ?? user.PhoneEvening ?? user.Mobile ?? String.Empty;
}
You can even define an extension method on string to convert empty strings to null and use it here, but I am just crazy.
If they can be an empty string, just use the other people answers. Jason's method is nice an clean.
回答6:
Just answering because I haven't seen the approach I use in this kind of scenarios in any of the existing answers.
What about...
_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;
It's inconvenient that you have to check by user nullness at the beginning because that forces to repeat string.Empty
, but nevertheless I think it's pretty readable.
My two cents ;)
回答7:
Adding some more parenthesis might make it more readable. You could also break it down into a series of if/else statements
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 = "";
}