What is this function I'm using? It works but why? - c#

I found this article on the webs and thought I'd try to apply the null string style method to my excel range value. Sometimes it has a value in it and sometimes it doesn't and obviously double doesn't like null values.
This is my little snippet.
double valTotal = (rngTotal.Value != null ? 1 : 0);
My question is what am I doing with this above code? It looks like an if statement in one line with the "1" being the "then" and the "0" being the "else". Is that right? And most importantly, what is the name of this syntax so I can find out more about this?

It's the conditional operator. (Sometimes incorrectly called the ternary operator; it's a ternary operator as it has three operands, but its name is the conditional operator. If another ternary operator is ever added to C#, "the ternary operator" will become an ambiguous/non-sensical phrase.)
Quick description:
The first operand is evaluated, and if the result is true, the second operand is evaluated and forms the overall value of the expression. Otherwise the third operand is evaluated and forms the overall value of the expression.
There's a little more detail to it in terms of type conversions etc, but that's the basic gist.
Importantly, the first operand is always evaluated exactly once, and only one of the second or third operand is evaluated. So for example, this is always safe:
string text = GetValueOrNull();
int length = text == null ? 5 : text.Length;
That can never throw a NullReferenceException as text.Length isn't evaluated if text == null is true.
It's also important that it's a single expression - that means you can use it in some places (such as variable initializers) where you couldn't use the if/else equivalent.
Closely related is the null-coalescing operator which is also worth knowing about.

It's the conditional operator:
http://msdn.microsoft.com/en-us/library/ty67wk28(v=vs.80).aspx

This is known as the conditional / ternary operator in C#. It's essentially short hand for the following
double valTotal;
if (rngTotal.Value !=null) {
valTotal = 1;
} else {
valTotal = 0;
}

It is the conditional operator. Yes, it acts like an "inline if". It is a handy shortcut for short if expressions. The part before the '?' is a Boolean condition if the Boolean condition is true then the part after the '?' is evaluated otherwise the part after the ':' is evaluated. In other words the '?' and ':' act like the 'then' and 'else' in an if statement.
See the links below for more detail.
https://msdn.microsoft.com/en-us/library/ty67wk28.aspx
The ternary (conditional) operator in C

It's called conditional operator:
http://msdn.microsoft.com/en-us/library/ty67wk28(v=vs.80).aspx

Related

Simplify conditional ternary expression in c#

I have a condition as shown below:
x.Customer == null ? false : x.Customer.CustomerData.IsSet
My IDE is saying to Simplify conditional ternary expression. Is there any other way to simplify this in dotnet? I recently started working with c# world it so kinda confuse on this.
Also can we also add a null check CustomerData too just like I have for Customer in a single line as well?
I tried like this -
Field("isSet", x => x.Customer?.CustomerData?.IsSet ?? false);
When I try this, it gives an error as -
An expression tree lambda may not contain conditional access
expression
The result of your expression is boolean so there's no need to write ternary operator. You can write it this way:
x.Customer != null && x.Customer.CustomerData.IsSet
Just try
bool result = x.Customer?.CustomerData?.IsSet ?? false
So if any of Customer or CutomerData is null, default will be false, otherwise IsSet will be returned.

Can the "?" symbol be used to cast types in C#? [duplicate]

This question already has answers here:
Question mark and colon in statement. What does it mean?
(7 answers)
Closed 5 years ago.
I found a piece of code online where there is this line:
new Claim(JwtClaimTypes.EmailVerified,
user.EmailConfirmed ? "true" : "false",
ClaimValueTypes.Boolean)
While the code works I'm not sure what does that specific line do. I know the "?" symbol is used to nullify Types, but can it be used to cast Types as well?
It is not for casting. It is just the conditional operator, an easy syntax to do an if-else code block. So if the expression before ? returns true, it executes the first expression ( the one followed by ?) and return the value and if the expression before ? returns false, it returns the return value of the second expression (followed by :)
So in your case, If the value of the expression user.EmailConfirmed is true the code will be same as
new Claim(JwtClaimTypes.EmailVerified, "true" , ClaimValueTypes.Boolean)
else (if it is false)
new Claim(JwtClaimTypes.EmailVerified, "false" , ClaimValueTypes.Boolean)
You can also call the ToString() method on the boolean value and then call ToLower() method to get true or false . If you ever want to try that, Here is how you do it
new Claim(JwtClaimTypes.EmailVerified, user.EmailConfirmed.ToString().ToLower(),
ClaimValueTypes.Boolean)
I would personally prefer the first approach ( conditional operator), but probably replace the magic strings with some constants

Null Coalescing for String to Int

I want to do a checking on a textbox, if null then assign zero, after that proceed with some calculation. I know there is a null coalescing (??) operator can help me, but I'm not sure is it possible for me to assign int when textbox is empty.
I tried to write something like this, but seems like is an error.
sdowntime = Convert.ToInt32(txtSDown.Text) ?? 0;
I get this
Error 98 Operator '??' cannot be applied to operands of type 'int' and 'int'
Anything I made it wrong or actually I should use another method? Please guide.
Thank you very much!
You could also use the TryParse method, like so:
int sdowntime;
int.TryParse(txtSDown.Text, out sdowntime);
If the TextBox is blank or contains a non-numeric value, the out parameter will be assigned the value 0. Otherwise, the appropriately parsed value is assigned. Please note, however, that you should always have client-side validation to ensure that non-numeric values are not entered by users in numeric fields.
You get the error because int is a value type. And since value types are not null-able, it is meaningless to use null-coalescing operator on them.
What you really need to do is check the null-ness of the text:
string textToParse = txtDown.Text ?? "0";
Edit: So I made a mistake and it has been pointed out that TextBox.Text can never be null.
Extra:
Even if you check for null, Convert.ToInt32 can fail if your text is not null, but empty ("" or String.Empty). You can use int.TryParse.
int sdowntime;
if (!int.TryParse(txtDown.Text ?? "0", out sdowntime))
{
// int.TryParse will assign 0 to sdowntime if it fails
// so watch out for that too.
}

Convert increment value

I tried to convert incremented value to string.
i++.ToString()
The above statement working fine.
++i.ToString()
This one showing error line. Why?
Because in the second expression the ToString() method of i is called first and the ++ operator is meaningless for strings. On the other hand, in your first expression, the integer i is get incremented by one and the method ToString() is called. So you get the string representation of your number. You could conver it, as already ulugbek-umirov pointed out in his comment:
(++i).ToString();
Please have a look here.
It is caused by the different operator precendence of i++ and ++i.
i++ belongs to "Primary" whereas ++i belongs to the "Unary" group. But since the . belongs also to "Primary" is has a higher precendence . So .ToString is executed first. You cannot use ++ operator on a string.
You can wrap it in paranthesis:
(++i).ToString()
Reference: Operators
Because the second means:
++(i.ToString()) // Oops, compiler error
and string type can not be incremented.
(++i).ToString() will do the trick.
The error is caused by the precedence of the operators being applied.
In your instruction you're trying to apply an int-increment to a string.
If you want to post increment you should do:
(++i).ToString();
Answers and comments saying that this is due to anything "executing first" are misleading. This problem is due to the higher precedence of . relative to ++(prefix). Order of evaluation has nothing to do with it really - especially since ++i.ToString() does not compile and therefore there is no evaluation at all (hence no order in which it happens).
See also precedence vs associativity vs order.
You have to options
make it in 2 times:
i++;
i.ToString();
Use parenthesis to set priority (first increase then convert to string)
(++i).ToString();
or
(i++).ToString();
Because when ++ is used as a postfix, it will increase its value immediately then covert it to string using ToString();
Instead if you use ++ as prefix operator then it will convert the existing value to string using ToString() then it will try to increment the value, so in this case you are getting error on increment a string value...
so try using parenthesis for increasing its precedence as (++i).ToString();

How do predicate parameters work syntactically in C#?

Some Object Relational Mapping (ORM) frameworks (such as LLBLGen) allow you to specify "predicate" parameters to the query methods, such as (simplified a bit):
var entities = adapter.FetchEntities(EntityType.Employee,
EmployeeFields.Salary > 50000);
How does that 2nd parameter work syntactically in C#? It kind of looks like a lambda expression, but it doesn't have the parameter part or the "=>". What is it? May need Jon Skeet for this one.
If you overloaded the ">" operator to return some kind of predicate object on your special "SuperDatabaseMapField" type, you could do such things.
That said, it seems vastly inferior in every way to taking a lambda expression instead (and parsing an expression tree if you have to.)
I agree with mquander's answer. The reason such a construct works is because of the way compilers evaluate expressions. In this case for LLBLGen, the second parameter expects something that can be evaluated to a boolean (for instance).
Operators (+, -, ***, /) are merely expressions that the compiler uses to build syntax trees which it uses to validate if certain combinations of left and right expressions are valid given the context ("+"). For instance a (string literal) + 2.4 (float) is obviously not valid in C#, and the compiler knows this from validating the expressions (string) (operator_add) (float).
Therefore, in order to make an odd scenario like the following work:
FetchEntities(EntityType.Employee,
EmployeeFields.Salary > ((EmployeeFields.DateOfBirth - 10) * 1.2) + 1024)
it would be necessary to overload the operators (- and *** and +) to return a new "predicate" object.
Ultimately such a statement would be translated into the following syntax tree (items in "()" are expression types for the purpose of this answer)
(BinaryComparison)
LeftSide: (Field_Reference) --> EmployeeFields.Salary
RightSide:
(MathematicOperator)
LeftSide:
(MathematicOperator)
LeftSide:
(MathematicOperator)
LeftSide: (Field_Reference) --> EmployeeFields.DateOfBirth
RightSide: (constant) --> 10
Operator: --> -
RightSide: (constant) --> 1.2
Operator: --> ***
RightSide: (constant) --> 1024
Operator: --> +
Operator: --> >
This is the whole basis on how things like lambda expressions and fluent query works. It all boils down to expression evaluation.
Lambda expressions are more... expressive in that they can touch objects and their fields and properties and methods and allow an arbitrary length syntax tree to be formed.

Categories