简体   繁体   中英

Ternary Best Practice

I have a bit of code, that while simple perhaps isn't immediately obvious as to what it does.

I found @(Model.Count() == 0 ? "no" : Model.Count().ToString()) @(Model.Count() == 1 ? "person" : "people")
@foreach (var item in Model) {
   <div>@item.Name at @item.Email</div>
}

And before I write lots of code like this, I wanted to know if this is a good way of doing this.

Thus the question is, in .NET is there a better framework way of doing this, or is the Ternary method fine

The premise is obviously

  • 0 records = I found no people
  • 1 record = I found 1 person
  • 2+ records = I found 2 people

In my opinion it is absolutely fine to use the Ternary conditional operator for this kind of condition.

Developers with experience understand it without thinking about it, but if you want to make it easy readable for beginners, you can also use an if and else construct.

But I would use Any() as @I4V mentioned in the comment.

I found @(Model.Any() ? Model.Count().ToString() : "no") @(Model.Count() == 1 ? "person" : "people")


@foreach (var item in Model) {
   <div>@item.Name at @item.Email</div>
}

If your doing it in a few places, an extension method would solve both your problems (readability & simplified code)

public static string PersonCountString(this IEnumerable<Person> personList)
{
    var count = personList.Count();
    return String.Format("{0} {1}", count > 0 ? count : "no",
                                    count == 1 ? "person" : "people");
}
...
I found (@Model.PersonCountString())

To answer your question: no, I find that oneliner not readable, it reads like @(() 0 ? "" : .().()) @(.() == 1 ? "" : "") to me, not to mention the multiple calls to .Count() .

You could create a (shared) helper method like this:

string GetCountWithDescription(int count, 
                               string singleItemDescription, 
                               string multipleItemsDescription)
{
    switch (count)
    {
        case 0:
            return "no " + multipleItemsDescription;
        case 1:
            return "1 " + singleItemDescription;
        default:            
            return count + " " + multipleItemsDescription;
    }
}

Reusable too, so you can stick it in a separate file so it won't clutter your code, and you can simply call it in from every view like this:

@GetCountWithDescription(Model.Count(), "person", "people")

What do you try to achieve? Better readability or faster code (development)? If the aim is for better readability, then I suggest to keep the ternary operation inside strings, for example:

string modelCountStr = Model.Count() == 0 ? "no" : Model.Count().ToString(); string modelPluralStr = Model.Count() == 1 ? "person" : "people";

Considering you will have to use Count() if any users are present:

@{ 
    var count = Model.Count();
}

I found @(count == 0 ? "no" : count) @(count == 1 ? " person" : " people")

Another way to make it more readable would be to opt for a solution where there are as few or ideally zero conditionals involved, if possible.

This is my take:

@{ 
    var count = Model.Count(); 
}
I found @string.Format(new[] { "no people", "{0} person", "{0} people"} [Math.Min(count, 2)], count)

Arguably Math.Min is responsible for some kind of branching, but I think this is much easier to understand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM