C# Null Conditional in Ternary condition - c#

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,

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");

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?)

Related

Checking for text boxes not null

If I have two text boxes and I want to know if both of their Text properties are null I can do this:
if (string.IsNullOrWhiteSpace(txtNameFirst.Text) &&
string.IsNullOrWhiteSpace(txtNameLast.Text))
{}
That will check if both are null or blank, but is there a way to say if not null or white space? Essentially, the inverse?
Put a ! before the string.IsNullOrWhiteSpace() method call.
if (!string.IsNullOrWhiteSpace(txtNameFirst.Text) &&
!string.IsNullOrWhiteSpace(txtNameLast.Text))
{
// ...
}
There are several ways:
if (!string.IsNullOrWhiteSpace(txtNameFirst.Text) &&
!string.IsNullOrWhiteSpace(txtNameLast.Text))
{}
or
if (string.IsNullOrWhiteSpace(txtNameFirst.Text) == false &&
string.IsNullOrWhiteSpace(txtNameLast.Text) == false)
{}
or
if (txtNameFirst.Text?.Trim().Length > 0 &&
txtNameLast.Text?.Trim().Length > 0)
{}
As everyone else is saying, !string.IsNullOrWhiteSpace() will work for you.
Based on this question I assume you didn't know this, but the logical negation operator ! is a unary operator that negates its operand. It is defined for bool and returns true if and only if its operand is false.
So another example, let's say I want to see if the string The dog barked loudly contains the letter a, I would type string.Contains("a"). However, if I wanted to to make sure it does not contain the letter a, I would type !string.Contains("a").

Continue as First Statement in Concise If Else

I have the following if else statement inside of a foreach loop:
string date = GetDate(item)
if (date == null)
{
continue;
}
else
{
article.Date = date;
}
And I would like to write this in the concise format using ? ::
string date = GetDate(item)
date == null ? continue : article.Date = date;
From what I gather, this should work, as it is in the format condition ? first_expression : second_expression;, where first_expression is continue, however in Visual Studio 2015 I am seeing these errors for the given areas:
continue
Invalid expression term 'continue'
Syntax error, ':' expected
Invalid expression term 'continue'
; expected
:
; expected
: expected
Is it possible to use continue in this types of If/Else? If not, is there any reason for this?
https://msdn.microsoft.com/en-gb/library/ms173144.aspx
An expression is a sequence of one or more operands and zero or more operators that can be evaluated to a single value, object, method, or namespace
continue is not an expression
Your code is trying to assign continue to to your "date" variable. This doesn't make sense. I'm afraid there's no way to use the ternary operator for what you're trying to accomplish.
Well,
string date = GetDate(item)
date == null ? continue : article.Date = date;
Conditional ?: operator must return something, you can read it as:
// if(smth) { return smth} else { return smthElse; }
var result = a ? b : c;
Obviously you cannot return continue because it is not a value.
What you can do is to assign the same value if returned result is null and check it using null coalescing operator. Assuming that there are no further operations in loop this code could be refactored to something like :
article.Date = GetDate(item) ?? article.Date;
Try this one, With the default you can add default time 1/1/0001 12:00:00 AM value to your variable date if the date is null,
date == null ? default(DateTime): article.Date = date;

how to insert if else in equal statement

I need to set the condition as below code.
_orderStatus = Request.QueryString["order"] != null ? Request.QueryString["order"] : _orderStatus != "" ? _orderStatus : "pending";
Currently the condition only applied to show pending order. How can i change and add to get as below condtion:
if Request.QueryString["order"] != null then
_orderStatus: "pending"
else
_orderStatus: "confirmed"
Thanks
should be like this
_orderStatus = Request.QueryString["order"] != null ? "pending" : "Confirmed";
Additional note to the above answer: Let me copy your requirement to the answer:
if Request.QueryString["order"] != null then _orderStatus: "pending"
else _orderStatus: "confirmed"
Here you need to assign the result to the variable _orderStatus, The conditional operator will do that for you, you need not to do an additional assignment within the operator.
While using conditional operator if.. then can be replaced with ?
and else will be replaced by : and the result will be assigned to
the _orderStatus.
Now look into your code( which included in the answer), and apply the replacements as i said. then you will get the answer like the following:
_orderStatus = Request.QueryString["order"] != null ? "pending" : "Confirmed";
The bets way of checking your query string then, try this
if (!string.IsNullOrEmpty(Request.QueryString["order"]))
_orderStatus = "pending";
else
_orderStatus = "confirmed";
There are multiple ways to do either u can simply check the for null or Empty by using if conditon like this
if (!string.IsNullOrEmpty(Request.QueryString["order"]))
_orderStatus = "pending";
else
_orderStatus = "confirmed";
or you can use conditional expression For reference u can go through this link
For your question u can use this way
_orderStatus = Request.QueryString["order"] != null ? "pending" : "Confirmed";
There's no reason to expect any difference in performance.
In my opinion, the ternary operator should only be used if all three operands are very concise and easy to read. Otherwise I think it has the potential to make code harder to read.
I think a lot of people mis-use this operator by using too much logic into one long line of code. I personally won't use it unless the whole line is less than about 80 characters.

AppSettings value is returning null in ternary operator

I've been moving some of my string values into my web config, however, one value is returning null when used as a condition in a ternary operator.
Web Config:
<add key="Main.Root" value="www.blah.com" />
AppSettings.cs:
public struct SiteRoots
{
public static readonly string Test = ConfigurationManager.AppSettings["Main.Root"];
}
Code:
ViewBag.Profile = HttpContext.IsDebuggingEnabled || HttpContext.Request.Url.Host == AppSettings.SiteRoots.Test ? AppSettings.GTMKeys.Test : AppSettings.GTMKeys.Live;
If I use "AppSettings.SiteRoots.Test" anywhere else on the page, it returns the correct value, it only seems to return null when used as a condition inside the ternary operator.
Enclose the ternary expression in paraenthesis, also ensure AppSettings.GTMKeys.Test and AppSettings.GTMKeys.Live gives boolean to that it could be used with ||.
ViewBag.Profile = HttpContext.IsDebuggingEnabled || (HttpContext.Request.Url.Host == AppSettings.SiteRoots.Test ? AppSettings.GTMKeys.Test : AppSettings.GTMKeys.Live);
You probably do not need HttpContext.IsDebuggingEnabled in your expression
ViewBag.Profile = HttpContext.Request.Url.Host == AppSettings.SiteRoots.Test ? AppSettings.GTMKeys.Test : AppSettings.GTMKeys.Live;

What is this confusing expression "a == b ? value1 : value2"?

I am new to learning C# and Silverlight and have been given some application files by my employer to start learning. I am able to understand most of the logic, methods and syntax used in C# but there is one line which is very confusing to me. I dont have access to my seniors right now to ask them so the logic behind it so I thought I will ask here.
Take a look at this:
In a .xaml.cs file:
List<object> lst = new List<object>();
lst.Add(GP.mpl.A);
lst.Add(GP.mpl.B);
lst.Add(GP.mpl.C);
lst.Add(GP.mpl.StnNo);
In a different .cs file:
public int StnNo = Convert.ToInt32(lst[3].ToString() == string.Empty ? 0 : Convert.ToInt32(lst[3].ToString()));
I understand that StnNo is being received from lst[3] and converted to Integer through
Convert.ToInt32(lst[3].ToString()
But I dont understand this part:
== string.Empty ? 0 : Convert.ToInt32(lst[3].ToString())
Could you tell me what's going on there? I have done multiple searches on google but didn't find anything related. Thanks for any help.
? is a ternary operator.
condition ? first_expression : second_expression;
?: Operator (C# Reference)
So in you example,
public int StnNo = Convert.ToInt32(lst[3].ToString() == string.Empty ? 0 : Convert.ToInt32(lst[3].ToString()));
is equal to
public int StnNo;
if (lst[3].ToString() == string.Empty)
{
StnNo = 0;
}
else
{
StnNo = Convert.ToInt32(lst[3].ToString());
}
This is the conditional, sometimes referred to as ternary, operator.
It takes the form boolean expression ? true value : false value.
In C#, the true value and false value must be of the same type, or one must be implicitly convertible to the other (but not both). Otherwise, you must legally and explicitly cast one or both to a common type.
In your code, you have
int StnNo = Convert.ToInt32(lst[3].ToString() == string.Empty ? 0 : Convert.ToInt32(lst[3].ToString()));
it is producing the functional equivalent of
int temp;
if (lst[3].ToString() == string.Empty)
temp= 0;
else
temp = Convert.ToInt32(lst[3].ToString());
int StnNo = Convert.ToInt32(temp);
You can see the outer Convert.ToInt32 in your code is actually redundant and can be eliminated.
int StnNo = lst[3].ToString() == string.Empty ? 0 : Convert.ToInt32(lst[3].ToString());
That's a very poorly written way of saying "if lst[3] is empty, then use 0, otherwise parse lst[3]" - because as your question illustrates, it's harder to tell what exactly the original developer intended.
To make it more clear, let's dissect it.
lst[3].ToString() == string.Empty means "does the lst[3] evaluate to an empty string?"
? X : Y means "if so, X, otherwise Y.
0 a constant value
Convert.ToInt32(lst[3].ToString()) parses the value as an lst[3] integer.
Finally the whole expression is passed into another Convert.ToInt32, but this is entirely unnecessary because the result of the conditional expression is always an int.
Since you don't have to call Convert.ToInt32 twice, a better way of writing this would be:
public int StnNo =
(lst[3].ToString() == string.Empty
? 0
: Convert.ToInt32(lst[3].ToString()));
An even better way of writing this would be:
int StnNo;
int.TryParse(lst[3], out StnNo);
It's more lines of code, but it's a lot easier to read.
== string.Empty ? 0 : Convert.ToInt32(lst[3].ToString()) is to check that if lst[3] does not contain any value, then 0 will be assigned to StnNo.

Categories

Resources