Mukesh Singh
Mukesh Singh

Reputation: 323

What is the meaning of below c# code (Chaining the Conditional Ternary Operator)

ViewBag.StatusMessage =
                message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
                : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
                : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
                : message == ManageMessageId.Error ? "An error has occurred."
                : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
                : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
                : "";

Upvotes: 2

Views: 313

Answers (1)

StuartLC
StuartLC

Reputation: 107407

(The code listed is from the scaffolded ManageController in an ASP.Net MVC 5 app)

It is a chained use of the conditional operator

Although the same result could be achieved with nested if statements:

if (message == ManageMessageId.ChangePasswordSuccess)
    ViewBag.StatusMessage = "Your password has been changed."
else if (message == ManageMessageId.SetPasswordSuccess)
    ViewBag.StatusMessage = "Your password has been set."
... 

or a switch statement

switch (message)
   case ManageMessageId.ChangePasswordSuccess:
      ViewBag.StatusMessage = "Your password has been changed.";
      break;
   case ManageMessageId.SetPasswordSuccess:
      ViewBag.StatusMessage = "Your password has been set.";
      break;
    ...

Using the conditional operator in chained fashion has the benefit of avoiding the repetitive assignment of ViewBag.StatusMessage, as it allows projection of a result which must be of the same type, and thus allows a single assignment. It also discourages coding side-effecting behaviour which is possible in an if or switch statement.

Edit, other alternatives

If the number of permutations becomes very large, I would opt for a Dictionary lookup pattern to map the ManageMessageId values to strings to set in the ManageController's Viewbag, as this will reduce the number of comparisons in order to match the appropriate key:

private static readonly IDictionary<ManageMessageId, string> _messageDictionary 
= new Dictionary<ManageMessageId, string>
  {
      {ManageMessageId.ChangePasswordSuccess, "Your password has been changed."},
      {ManageMessageId.SetPasswordSuccess, "Your password has been set."},
      // ...
  };

The equivalent mapping code would then be simply (with just a single use of the conditional operator) - ManageMessageId is an enum:

public async Task<ActionResult> Index(ManageMessageId? message)
{
   ViewBag.StatusMessage = (message.HasValue)
      ? _messageDictionary[message.Value]
      : "";

Upvotes: 4

Related Questions