1

Am refactoring some old code and see something in the following format:

Type = rec["IsFlagged"]?.ToString() == "True" ? "Yes" : "No"

which should not work if rec["IsFlagged"] is null, in which case I need to return null. How would one refactor to keep code in one line, if possible?

I can do something like but am wondering if the following can be achieved in one line to have minimal changes to code

    if (rec["IsFlagged"] != null)
    {
       return rec["IsFlagged"].ToString() == "True" ? "Yes" : "No"
    }
    else 
    {
        return null
    }

Thanks,

5
  • 3
    null == "True" would be false, since null is not equal to a string "True", so should result in "No" Commented Oct 26, 2021 at 23:02
  • 1
    rec["IsFlagged"]? means return null if rec["IsFlagged"]? is null, otherwise return .ToString() Commented Oct 26, 2021 at 23:03
  • 1
    There likely is no way to achieve what you've show in a single statement (assuming that "one line" means a single statement, not just removing new lines from the code) because only half of the choices have return (when rec["IsFlagged"] is null code continues)... Make sure what question is asking is what you want (probably the case because second code is not equivalent the first one) Commented Oct 26, 2021 at 23:06
  • Thanks... you guys were too quick for me.. :)... I edited the question and added some more information. Commented Oct 26, 2021 at 23:07
  • 1
    It looks like rec["IsFlagged"] is a bool value when it's not null. Can you confirm that? Commented Oct 26, 2021 at 23:14

2 Answers 2

1

The original code works fine.

rec["IsFlagged"]?.ToString() == "True" ? "Yes" : "No"

The ? operator before .ToString() prevents the method from being called if null. The result of rec["IsFlagged"]?.ToString() would be null

Then, it compares null to "True" which is false (they are not equal).

The ternary operator then evaluates "No" and assigns it to the lvalue.

EDIT So, now you want 3 possible results: "Yes", "No" or null. A single ternary only gives you two choices. There are many possibilities and yours is fine, unless you have multiple places doing something similar. In that case, you could use an extension method:

public String CheckTrue(this object input) {
    return input?.ToString() == "True" ? "Yes" : "No"
}

and then in your specific case:

return rec["IsFlagged"]?.CheckTrue()

Another alternative is to use multiple ternary operators?

return rec["IsFlagged"]==null ? null : (rec["IsFlagged"].ToString() == "True" ? "Yes" : "No");
Sign up to request clarification or add additional context in comments.

2 Comments

Oof, nested ternaries are a slippery slope! 😀
Using multiple ternary works (I know its difficult to read and debug) but opted for it since it has minimal changes to existing code. Thanks to everyone who proposed a solution
0

This will do want you want..

rec["IsFlagged"]?.ToString().Replace("True","Yes").Replace("False","No")

.. but you perhaps shouldn't want to do it!

I prefer Garr's suggestions, though if it's a bool inside rec (is rec a DataRow?) I'd skip the ToString/compare with string and just use it as a bool once we know it's not null

return rec["IsFlagged"]==null ? null : ((bool)rec["IsFlagged"] ? "Yes" : "No");

But all in I like the extension method approach more, and we can tweak it some, leveraging conversion between a bool-or-null-stored-in-object and bool?:

public static string ToNullaboolString(this bool? x, string t = "Yes", string f = "No", string n = null){
  if(x.HasValue) 
    return x.Value ? t: f;
  return n;
}

Calling it like:

((bool?)rec["IsXxx"]).ToNullaboolString()

or supplying parameters if you want to change the strings returned (localization?)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.