FirstOrDefault() unable to couple with ?? operator - c#

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

Related

C# Null propagating operator / Conditional access expression & if blocks

The Null propagating operator / Conditional access expression coming in c#-6.0 looks like quite a handy feature. But I'm curious if it will help solve the problem of checking if a child member is not null and then calling a Boolean method on said child member inside an if block:
public class Container<int>{
IEnumerable<int> Objects {get;set;}
}
public Container BuildContainer()
{
var c = new Container();
if (/* Some Random Condition */)
c.Objects = new List<int>{1,2,4};
}
public void Test()
{
var c = BuildContainer();
//Old way
if ( null != c && null != c.Objects && c.Objects.Any())
Console.Write("Container has items!");
//C# 6 way?
if (c?.Object?.Any())
Console.Write("Container has items!");
}
Will c?.Object?.Any() compile? If the propagating operator short circuits (I assume that's the right term) to null then you have if (null), which isn't valid.
Will the C# team address this concern or am I missing the intended use case for the null propagating operator?
It won't work this way. You can just skip the explanation and see the code below :)
As you know ?. operator will return null if a child member is null. But what happens if we try to get a non-nullable member, like the Any() method, that returns bool? The answer is that the compiler will "wrap" a return value in Nullable<>. For example, Object?.Any() will give us bool? (which is Nullable<bool>), not bool.
The only thing that doesn't let us use this expression in the if statement is that it can't be implicitly casted to bool. But you can do comparison explicitly, I prefer comparing to true like this:
if (c?.Object?.Any() == true)
Console.Write("Container has items!");
Thanks to #DaveSexton there's another way:
if (c?.Object?.Any() ?? false)
Console.Write("Container has items!");
But as for me, comparison to true seems more natural :)
Null-conditional operator would return null or the value at the end of expression. For value types It will return result in Nullable<T>, so in your case it would be Nullabe<bool>. If we look at the example in the document for Upcoming Features in C# (specified here), it has an example:
int? first = customers?[0].Orders.Count();
In the above example, instead of int, Nullable<int> would be returned. For bool it will return Nullable<bool>.
If you try the following code in Visual Studio "14" CTP:
Nullable<bool> ifExist = c?.Objects?.Any();
The result of the above line would be a Nullable<bool>/bool?. Later you can do the comparison like:
Using null-coalescing operator ??
if (c?.Object?.Any() ?? false)
Using Nullable<T>.GetValueOrDefault Method
if ((c?.Objects?.Any()).GetValueOrDefault())
Using comparison against true
if (c?.Objects?.Any() == true)
var x = c?.Objects?.Any() is going to give you a nullable boolean, and as others have said, this means you can use an equality operator like this
x == true
or you can use null coalescing like this to have your result not be nullable
var x = c?.Objects?.Any() ?? false
But, personally, I think that 3-state (nullable) booleans are code smell. Even if this one is practically invisible, its existence should encourage you to think about what you are actually trying to do and determine if a nullable boolean is actually the way to go. In this case, I think that what you really want to do is something like this -
var objects = c?.Objects ?? Enumerable.Empty<Object>();
if (objects.Any())
{
...
}
Put that in an extension method and it will be even more succinct -
public static bool IsNullOrEmpty<T>(this IEnumerable<T> collection)
{
return !(collection ?? Enumerable.Empty<T>()).Any()
}

How to return null if using SingleOrDefault() and searching a list of numbers for a number not in list?

When querying a list of positive numbers using SingleOrDefault(), how can I return null, or a custom value like -1, when a number isn't found in the list, instead of the type's default value (0 in this case)?
You could use:
var first = theIntegers
.Cast<int?>()
.SingleOrDefault(i => i == theValue) ?? valueIfNotFound;
This works by casting the items to a Nullable<int>, then using the null-coalescing operator to return the value you choose if null was returned (ie: not found).
Note this will throw if you have more than one matching item. If you don't want that behavior, use FirstOrDefault instead of SingleOrDefault.
You can use DefaultIfEmpty to specify a custom default value for an empty collection:
var value = numbers.Where(MyFilter)
.DefaultIfEmpty(-1) //or any other default value you want
.Single(); //OrDefault not needed; DefaultIfEmpty ensures there is an item
You have to change the type in your list to int? ( a nullable int ). The default value which you return will be 0 for an integer. For reference types it will be null. Without overloading the method you can't make the default retrurn value a custome value.
Maybe your question is simplified so this does not apply, but if you are only looking for a number you already know and want to return an arbitrary number if it's not in the list, you can use the Any-Extension method:
int numberToLookFor = 42;
int arbitraryReturnOnNotFound = 17;
int result = numbers.Any( n => n == numberToLookFor ) ? numberToLookFor : arbitraryReturnIfNotFound;

C# equivalent to JavaScript "OR assignment"

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.

Rewrite HasValue to the ?? Operators

Is it safe to rewrite the following code:
bool b = foo.bar.HasValue ? foo.bar.Value : false;
to
bool b = foo.bar.Value ?? false;
where bar is the nullable type bool?
The easiest fix there is
bool b = foo.bar.GetValueOrDefault();
which is also actually cheaper than .Value as it omits the has-value check. It will default to default(T) , which is indeed false here (it just returns the value of the underlying T field, without any checks at all).
If you need a different default to default(T), then:
var value = yourNullable.GetValueOrDefault(yourPreferredValue);
What you want is:
bool b = foo.bar ?? false;
This is (surprisingly) safe and an intended use for the null-coalescing operator.
The ?? operator is called the null-coalescing operator and is used to define a default value for a nullable value types as well as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand.
Source: http://msdn.microsoft.com/en-us/library/ms173224.aspx
In the case of Nullable<T>, it is functionally equivalent to Nullable<T>.GetValueOrDefault(T defaultValue).
The code:
bool b = foo.bar.Value ?? false;
Will cause a compiler-error, because you cannot apply the operator to value types, and Nullable<T>.Value always returns a value-type (or throws an exception when there is no value).
No - this is not safe.
The line:
bool b = foo.bar.Value ?? false;
will throw an InvalidOperationException if foo.bar has no value.
Instead use
var b = foo.bar ?? false;
Update - I just learned about .GetValueOrDefault(); from the other answers - that looks like a very good suggestion to use!
Update 2 - #ProgrammingHero's answer is also correct (+1 added!) - the line:
bool b = foo.bar.Value ?? false
actually won't compile - because of Error 50 Operator '??' cannot be applied to operands of type 'bool' and 'bool'
Nope.
The Value property returns a value if
one is assigned, otherwise a
System.InvalidOperationException is
thrown.
From: http://msdn.microsoft.com/en-us/library/1t3y8s4s%28v=vs.80%29.aspx
So if hasValue is false then you will get an exception thrown in your second one when you try to run it.
ffoo.bar ?? false would be more safer to use
bar.Value ?? false
has compilation error, because left operand of ?? operator should be of reference or nullable type.
Maybe you have a look at this article in Stackoverflow too - it is an elegant null checking in the style obj.IfNotNull(lambdaExpression) - returning the object you want if obj is not null otherwise just null (but without throwing an exception).
I used it with the Entity Framework if you're accessing a referenced entity, e.g.
var str=Entity1.Entity2.IfNotNull(x=>x.EntityDescription) ?? string.Empty
which returns EntityDescription contained in Entity2 which is referenced by Entity1 - or an empty string if any object Entity1 or Entity2 is null. Without IfNotNull you would get a long and ugly expression.
The extension method IfNotNull is defined there as follows:
public static TOut IfNotNull<TIn, TOut>(this TIn v, Func<TIn, TOut> f)
where TIn : class
where TOut: class
{
if (v == null) return null; else return f(v);
}
Update:
If you update the code to C# version 6.0 (.NET Framework 4.6 - but seems to support older frameworks 4.x too), there is a new operator available which makes this task easy: The "elvis" operator ?..
It works as follows:
var str=(Entity1.Entity2?.EntityDescription) ?? string.Empty
In this case, if Entity2 is null, evaluation stops and (...) becomes null - after which the ?? string.empty part replaces null by string.Empty. In other words, it works the same way as .IfNotNull(...) would.
foo.bar.Value represents the non-nullable value when there is one, and throws an InvalidOperationException if there’s no real value.

How can I round a C# double nullable type?

I want to round a double? value so that if its value is 2.3 the result should be 2 but if the input is null then the result should be null.
There is no direct way to round a nullable double. You need to check if the variable has a value: if yes, round it; otherwise, return null.
You need to cast a bit if you do this using the conditional ?: operator:
double? result = myNullableDouble.HasValue
? (double?)Math.Round(myNullableDouble.Value)
: null;
Alternatively:
double? result = null;
if (myNullableDouble.HasValue)
{
result = Math.Round(myNullableDouble.Value);
}
As others have pointed out, it is easy enough to do this as a one-off. To do it in general:
static Func<T?, T?> LiftToNullable<T>(Func<T, T> func) where T : struct
{
return n=> n == null ? (T?) null : (T?) func(n.Value);
}
And now you can say:
var NullableRound = LiftToNullable<double>(Math.Round);
double? d = NullableRound(null);
And hey, now you can do this with any method that takes and returns a value type.
return d.HasValue ? Math.Round(d.Value) : (double?)null;

Categories

Resources