Handling a conditional statement in a single line [duplicate] - c#

This question already has answers here:
How does the ternary operator work?
(12 answers)
Closed 2 years ago.
Is it possible to write following C# code in a line without if and else?
string res = "";
if (!string.IsNullOrEmpty(var1))
res = string.Format("{0}/{1}", var1, var2);
else
res = var2;

Try this,
string res = !string.IsNullOrEmpty(var1) ? string.Format("{0}/{1}", var1, var2) : var2;
Basically,
(if this statement is true (like if block's condition part)) ? (this section works) : ((else) this section works);
Hope this helps,

The conditional operator ?:, also known as the ternary conditional operator, evaluates a Boolean expression and returns the result of one of the two expressions, depending on whether the Boolean expression evaluates to true or false.
The syntax for the conditional operator is as follows:
condition ? consequent : alternative
So the code line you are requested is
string res = !string.IsNullOrEmpty(var1) ? string.Format("{0}/{1}", var1, var2) : var2;

Tecnically, you can hide if within ternary operator ?:
string res = $"{(!string.IsNullOrEmpty(var1) ? $"{var1}/" : "")}{var2}";
but what for?

Related

Is there a shorthand for the ternary operator in C#?

Background
In PHP there is a shorthand for the ternary operator:
$value = "";
echo $value ?: "value was empty"; // same as $value == "" ? "value was empty" : $value;
In JS there's also an equivalent:
var value = "";
var ret = value || "value was empty"; // same as var ret = value == "" ? "value was empty" : value;
But in C#, there's (as far as i know) only the "full" version works:
string Value = "";
string Result = Value == string.Empty ? "value was empty" : Value;
So my question is: Is there a shorthand for the ternary operator in C#, and if not, is there a workaround?
Research
I found the following questions, but they're referring to use the ternary operator as shorthand to if-else:
shorthand If Statements: C#
Benefits of using the conditional ?: (ternary) operator
And this one, but it's concerning Java:
Is there a PHP like short version of the ternary operator in Java?
What I have tried
Use the shorthand style of PHP (Failed due to syntax error)
string Value = "";
string Result = Value ?: "value was empty";
Use the shorthand style of JS (Failed because "The || operator is not applicable to string and string.")
string Value = "";
string Result = Value || "value was empty";
There is no shorthand for when the string is empty. There is a shorthand for when the string is null :
string Value = null;
string Result = Value ?? "value was null";
The coalesce ?? operator works only on null, but you could "customize" the behavior with an extension method:
public static class StringExtensions
{
public static string Coalesce(this string value, string #default)
{
return string.IsNullOrEmpty(value)
? value
: #default;
}
}
and you use it like this:
var s = stringValue.Coalesce("value was empty or null");
But I don't think it is much better than the ternary.
Note: the # allows you to use reserved words as variable names.

How to apply Null-Conditional Operator on blank strings?

I have a string value and need to convert that to decimal.
var str = null;
decimal number;
decimal d = Decimal.TryParse(str, out number) ? number : 0M;
It's working fine.
Now I am trying to achieve the same thing by using the new Null-Conditional Operator of C# 6.0 . How can I do so?
I know it's a wrong attempt.
var str = null;
decimal d = str?.Convert.ToDecimal(str);
A blank (empty) string is not null, so you can't use that operator.
You could do:
decimal d = string.IsNullOrEmpty(str) ? 0M : Convert.ToDecimal(str);
EDIT: OK, now we're starting with a null string. In which case...
decimal d = (str == null) ? 0M : Convert.ToDecimal(str);
I still don't think that this is an appropriate time to use the null-conditional operator, because that's most useful when the ultimate result of the expression can be null - which is not true in your case.
According to msdn you can't do that as null conditional operator is:
Used to test for null before performing a member access (?.) or index
(?[) operation
and in this case you aren't indexing or accessing the input string members.
As the other answer stated the way to do that would be
decimal d = String.IsNullOrEmpty(str) ? default(decimal) : Convert.ToDecimal(str);
Not exactly answering the question, but I would create an extension method where you have the advantage of being able to formally call it on null values too.
This implementation gives the correct double if the input string is in a valid format (using the default formatting), and gives the optionally passed default value if string is null or empty or is in incorrect format.
public static double ConvertToDoubleOrDefault(this string input, double def = 0.0)
{
if (string.IsNullOrEmpty(str)) return def;
double result;
if (!double.TryParse(str, out result)) return def;
return result;
}
....
string test = "1234";
string test2 = null;
var d = test.ConvertToDoubleOrDefault(); // => 1234
d = test2.ConvertToDoubleOrDefault(); // => 0.0

C# "condition coalescing" operator

Is there any special expression or some kind or syntactic sugar built in in C# that would allow one to change a variable's value or leave it alone depending on condition?
I mean something that would do following:
str = (condition) ? "modifiedString" : str;
or
if (condition) str = "modifiedString";
But with simplicity of null coalescing operator. Something like
str = (condition) ?? "modifiedString"
How about
if(condition)
str = "modified"
Isn't that exactly what you want?

vb.net to c# conversion for IsDBNull not working

The following conversion doesn't work.
Error:"Only assignment, call, increment, decrement & new object can be
used as a statement"
VB.net
objUser.Email = IIf(IsDBNull(drow("Email")), "", drow("Email"))
C#
objUser.Email == (Information.IsDBNull(drow("Email")) ? "" : drow("Email"));
I need it in C#. Any ideas??
In C# = is asignment operator and == is comparison operator
Remove == and replace with =.
Assuming that drow is DataRow
objUser.Email = (drow.IsNull("Email") ? String.Empty : drow["Email"].ToString());
?: is ternary operator which always returns a value. In your case that value is being assigned to objUser.Email.
You have accidentally, used comparison operator instead of assignment operator.
objUser.Email == (Information.IsDBNull(drow("Email")) ? "" : drow("Email"));
should be, as you are not doing comparision, its an assignment.
objUser.Email = (Information.IsDBNull(drow("Email")) ? "" : drow("Email"));
You're using equal operator instead of assignment operator in the C# variant.
Change the == to = since what you want is assignment.
objUser.Email = (Information.IsDBNull(drow("Email")) ? "" : drow("Email"));
Try this:
objUser.Email = (DBNull.Value == drow("Email")) ? "" : drow("Email"));
See the Documentation for DbNull - where you will find examples:
From MSDN
private string AddFieldValue(string label, DataRow row,
string fieldName)
{
if (! DBNull.Value.Equals(row[fieldName]))
return (string) row[fieldName] + " ";
else
return String.Empty;
}

Using null coalescing in foreach statement

Trying to figure out how to get the null coalescing operator to work in a foreach loop.
I'm checking to see what a string ends with and based on that, route it to a certain method. Basically what I want to say is....
foreach (String s in strList)
{
if s.EndsWith("d") ?? Method1(s) ?? Method2(s) ?? "Unknown file type";
}
In attempting to do this, of course you get the "Operator ?? cannot be used on type bool and type string." I know there is other ways to do it, just want to see how it can be done with null coalescing.
Have a good weekend.
#Richard Ev: Oh yes of course. Switch, if else, etc. Was just curious how it
could be handled
#Jon Skeet: After reading your comments it hit me, this is just bad! I am
interested in two file extensions basically. If a file ends with "abc" for
instance, send to method 1, if the file ends with "xyz" send to method 2. But
what if a file ends with an extension of "hij"...boom, you're done.
Thanks to Brian and GenericTypeTea as well for the thoughful input
I'm content calling it closed.
It looks like you want to use the normal ternary operator, not null coalescing. Something like:
(s.EndsWith("d") ? Method1(s) : Method2(s)) ?? "Unknown file type";
This is equivalent to:
string result;
if (s.EndsWith("d"))
result = Method1(s);
else
result = Method2(s);
if (result == null)
result = "Unknown file type";
return result;
I think you want a combination of the conditional (ternary) operator and the null coalescing operator:
foreach (String s in strList)
{
string result = (s.EndsWith("d") ? Method1(s) : Method2(s))
?? "Unknown file type";
}
In simple english, this will do the following:
If s ends with d, then it will try Method1.
If s does not end with d then it will try Method2.
Then if the outcome is null, it will use "Unknown file type"
If the outcome is not null, it will use the result of either A or B
I think the compiler gave you the appropriate answer, you can't.
Null coalescing is essentially this if statement:
if(x == null)
DoY();
else
DoZ();
A boolean value cannot be null, so you can't coalesce it like that. I'm not sure what your other methods return, but it seems like you want a simple || operator here.
You should first use the ?? null coalescing operator to guard against a null s reference. Then use the ? ternary operator to choose between Method1 and Method2. Finally use the ?? null coalescing operator again to provide the default value.
foreach (string s in strList)
{
string computed = s;
computed = computed ?? String.Empty;
computed = computed.EndsWith("d") ? Method1(s) : Method2(s);
computed = computed ?? "Unknown file type";
}

Categories