C# equivalent to JavaScript "OR assignment" - c#

Does C# have an equivalent to JavaScript's assignment syntax var x = y || z;? In case you don't know, the result is not true/false. If y is defined, then it is assigned to x, otherwise z is assigned to x even if it is undefined.
Note that in JavaScript the variable still has to be declared: var test;

I think that you are looking for ?? operator.
MSDN Reference

var abc = blah ?? "default";
yep

This is what you are looking for
var x = y ?? z;

In C# there's no such notion as variable not being defined. Such operator doesn't make sense in C#.

Unlike JavaScript, C# is not dynamic but static language so that such operation is impossible - a compilation error will occur.
Imagine you're writing this if:
if(pizzaPrice == hamburgerPrice)
Before declaring the variables first:
decimal pizzaPrice;
decimal hamburgerPrice;
An error will occur on compile-time.
Update:
Even if the variables were declared it doesn't matter because C# does not support such a feature.
On the other hand, JavaScript is enforcing evaluation of the variable in if conditions by calling the ToBoolean method and if it's undefined or null it's equals to false and C# doesn't not contains such a behavior.
Look at this cool article: JavaScript pitfalls: null, false, undefined, NaN
But if you want to check if a variable is referencing to a null you can easily use the null coalescing operator "??" operator.
As the following:
var x = y ?? z;

Yes, there is: ??
string x = y ?? z;
Which basically calculates:
string x = y != null ? y : z
However, there are a few differences between Javascript and C#. As with JS, y and z must both be declared before hand. However, unlike JS, y and z must also be "assigned" in C# or a compiler error will be thrown as usual.
The operator requires a nullable type and it checks whether the first is null before returning the second. You can chain a whole bunch (a ?? b ?? c ?? d ?? e) if you want.
Note that a zero length string is not null.

Related

Elegant pattern for nullable types

I have the following construct:
MyType y = x.HasValue ? f(x) : null;
I am aware of a simple pattern that can be used if f was a member of x: MyType y = x.?f();
Is there a similar way to simplify the above code without changing the definition of f?
At present (November 2015), no such mechanism exists in C#.
Options are:
Change f to return null when parameters are null
Make an extension method
static R Call<P>(this P? parameter, Func<P, R> func)
{
if (parameter.HasValue)
return func(parameter.Value);
else
return default(R);
}
The closest thing I can think of is the null coalescing operator '??'
From MSDN:
// Set y to the value of x if x is NOT null; otherwise
// if x == null, set y to -1
y = x ?? -1;
Assuming f() can handle x being null and will return null if not, but then you could just do MyType y = f(x), which sounds like your best bet. Keep in mind, anything other than changing the function to handle x being null would require you to remember to do it on your own, as well as remember why, thus creating room to shoot your own foot and removing a layer of abstraction.
Also, doesn't f(x) take a nullable type and is therefore expecting one anyways?

?: Operator return void

I want to use the ?: operator intstead of if else
e.g.
var directory = new DirectoryInfo(path);
if (!directory.Exist())
{
directory.Create();
}
else
{
// do nothing
}
I tried to use ?: like this:
var directory = new DirectoryInfo(path);
!directory.Exist() ? directory.Create() : void;
but it says "Invalid expression term void", null also isn't working.
Can anyone tell me a solution?
In you scenario, only having a if condition is better suited.
Just for your understanding, A ternary Operator (?:) needs to result into a value in the right side and also needs a variable in left side to assign the result value e.g.:
x = (y== null) ? 0: 1;
This means assign 0 to x when y is null otherwise assign 1.
So in your example/scenario, you may write something like this to result into a directory creation status as below:
var newDirectoryCreated = (!directory.Exist()) ? directory.Create() : false;
This way, if new directory is created then newDirectoryCreated will assigned with true otherwise false.
Simply keep the if statement and remove the else clase since you aren't doing anything in there.
You're trying to use the ternary operator which, by definition, must return a value.
From the documentation:
The conditional operator (?:) returns one of two values depending on the value of a Boolean expression.
If your just looking for brevity, you could try this instead:
if (!directory.Exist())
directory.Create();
Ternary operator are not designed to replace if/else They are to simplify assignment and declaration. It should be able to assign the result the statement to something like variable or function. There major use are in assignment or reading.
Something like
var status = !directory.Exist() ? directory.Create() : false;
The correct solution would be to stick to native if condition. The following is enough:
var directory = new DirectoryInfo(path);
if (!directory.Exist())
{
directory.Create();
}
The ?: operator's behavior is roughly this:
for x ? y : z, it will return y if x is true, and otherwise it will return z.
From this we can deduce a couple of things:
both y and z must return something (it won't work if either of them evaluate to void), and
y and z must evaluate to the same type. (Imagine you had something like this: var r = x ? y : z;. Which type is r? Is it the type of y or z? We don't know which of them will be returned, but we have to pick a type at compile-time. So they have to return the same type.
In your case, both evaluate to void, which doesn't work. (And if you changed the last part to null, as you said you'd tried, then they evaluate to different types, one of which is void, which breaks both rules)
The conditional operator (?:) musts return one of two values depending on the value of a Boolean expression. So you can stick with if clause instead, it is still simple to understand rather than conditional operator:
var directory = new DirectoryInfo(path);
if (!directory.Exist()) directory.Create();
The ?: operator is an extention of the if-then-else construction.
The extention is in the then-block and the else-block. Where the then-block and the else-block return void for the if-then-else construciton it must return a type for the ?: operator. An aditional constraint for the types in the ?: operator is that the two types must be identical. This constraint is softened a bit by the fact that automatic casting will be used by the compiler to make the two types identical.
Code using ?: operators is in general shorter but also harder to read. This is one point to consider when replacing the if-then-else construct with the ?: operator. Unless your then-block and else-block are one liners it seldom is worth replacing it with the ?: operator.
The if-then construction is a limited version of the if-then-else construction (or visa versa, the if-then-else construction is an extention of the if-then construction). Since the if-then construction has only one code block, the then-block, it is not possible to replace the if-then construction with the ?: operator. You first have to extend the if-then construct with an empty else-block.
Examples:
// initialising an integer with an if-then construct.
int x = 0;
if (some_condition)
{
x = 1;
}
Think of this as if the then-blockreturns an integer.
It is not possible to use the ?: operator strait away.
// initialising an integer with an if-then-else construct.
int y;
if (some_condition)
{
y = 1;
}
else
{
y = 0;
}
Extended the if-then construct to a if-then-else construct and think of the then-block and else-block as returning a integer for witch the types coincidently ;-) match with each other.
It is possible to use the ?: operator in this case.
// initialising an integer with a ?: operator.
int z = (some_condition) ? 1 : 0;
About your code:
var directory = new DirectoryInfo(path);
if (!directory.Exist())
{
directory.Create();
}
In this case I do not see a sensible way to make the then-block returning a value. That makes using the ?: operator impossible or highly complicated with ugly code as a result. My advise, stick to the if-then construct in this case.

default assignment operator

Is there default assignment operator in c#?
Unlike C++, C# does not allow you to override the assignment operator.
For reference types, writing x = y will set x to refer to the same object (or null) that y does.
For value types, writing x = y will copy the fields in the y value to the x value.

FirstOrDefault() unable to couple with ?? operator

As far as I can understand, the linq method FirstOrDefault() returns null if a record-set is empty. Why can't use the ?? operator against the function? Like so:
Double d = new Double[]{}.FirstOrDefault() ?? 0.0;
Update
I don't want to check if d is null later on in my code. And doing:
Double d new Double[]{}.FirstOrDefault() == null
? 0.0
: new Double[]{}.FirstOrDefault();
... or:
var r = new Double[]{}.FirstOrDefault();
Double d = r == null ? 0.0 : r;
... seems a bit overkill--I'd like to do this null-check in one line of code.
Actually, FirstOrDefault<T>() returns T, which is either a value or default(T).
default(T) is either null or (T)0 for value types (like double)
Because the null-coalescing operator (??) applies only to nullable reference types while Double is a value type. You could use a nullable double instead (double?).
The method is called FirstOrDefault not FirstOrNull, i.e. it will return 0, the default value of a double anyway so there isn't a need for the ??.
Making it nullable should work. But, then your making it nullable, all depends on your scenario...
Double d = new Double?[] { }.FirstOrDefault() ?? 0.0;
Although others have answered why you have compilation problems here, you are right that this is problematic for value types. To my knowledge, there is no way of knowing in this case whether a result of zero was because the first item really was zero, or because the IEnumerable<double>was empty.
In the example you have given, the fallback value is zero anyway, so all you need is:
var r = new double[]{...}.FirstOrDefault();
Assuming you had a non-zero fallback value, you have a few options:
var r = !myDoubles.Any() ? fallback : myDoubles.First();
or
var r = myDoubles.Cast<double?>().FirstOrDefault() ?? fallback;
If you have Zen Linq Extensions, you can do:
var r = myDoubles.FirstOrFallback(fallback);

Why doesn't attempting to add to a null value throw an InvalidOperationException?

int? x = null;
x = x + 1; // Works, but x remains null
I would expect the compiler to attempt to cast x as an int, but apparently it does not.
Edit by 280Z28: Changed NullReferenceException to InvalidOperationException, which is what Nullable<T>.Value throws when HasValue is false.
This is per the specification for lifted binary operators. From §7.2.7:
For the binary operators
+ - * / % & | ^ << >>
a lifted form of an operator exists if the operand and result types are all non-nullable value types. The lifted form is constructed by adding a single ? modifier to each operand and result type. The lifted operator produces a null value if one or both operands are null (an exception being the & and | operators of the bool? type, as described in §7.10.3). Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result.
The reasoning is this: you are to think of null for a nullable type as meaning "I do not know what the value is." What is the result of "I don't know" plus one? "I don't know." Thus, the result should be null.
Nullables are never actually null references. They are always object references. Their internal classes override the == and = operators. If they are being compared to null, they'll return the value of the HasValue property.
Why would you expect the compiler to cast it as int when you've declared it as Nullable? The compiler is doing what you've told it to do and null +1 = null.
You'll have to cast explicitly or check x.HasValue before attempting to add an int.
The reason for this is that the compiler creates a 'lifted' operator for nullable types - in this case it is something like:
public static int? operator +(int? a, int? b)
{
return (a == null || b == null) ? (int?)null : a.Value + b.Value
}
I think if you try to assign the result to a non-nullable value, the compiler will be forced to use the non-nullable overload and convert x to an int.
e.g. int i = x + 1; //throws runtime exception
Unfortunately it doesn't. The X in x = X + 1 is null as in the first line so you're adding 1 to null, which equals null.
As it's a nullable int, you can use x.HasValue to check if it has a value, and then x.Value to get the actual int value out
Regardless of whether x is actually never null, that's not even the point.
The point is, when have you ever seen a NullReferenceException when trying to perform an addition?
The following example doesn't throw a NullReferenceException either and is perfectly valid.
string hello = null;
string world = "world";
string hw = hello+world;
You would only get a NullReferenceException if you try to access a member on an object that is null.
int? can never be null because it is a struct. Structs live on the stack and the stack does not handle null well.
See What is a NullPointerException, and how do I fix it?
Also, the nullable types have 2 very useful properties : HasValue, Value
This code:
if (x != null)
{
return (int) x;
}
Should be refactored to this:
if (x.HasValue)
{
return x.Value;
}

Categories

Resources