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

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()
}

Related

Implicit nullable cast inside if condition

I recently found some code with nullable if condition like this:
bool? nullableVariable;
//some lines of code involving nullableVariable
if (nullableVariable == true)
{
//some other lines of code
}
at first sight I thought it as potentially exception prone. My opinion was based on the fact that:
bool? nullableVariable = null;
bool variable = (bool)nullableVariable
would raise error System.InvalidOperationException: 'Nullable object must have a value.' and I expected that inside the if (nullableVariable == true) statement a cast of left operand from bool? to bool would be performed (my impression confirmed by the fact that moving cursor on == operator results in Visual Studio hint bool bool.operator == (bool left, bool right)).
Given that, I've been surprised seeing that:
bool? nullableVariable = null;
if (nullableVariable == true)
{
//some other lines of code
}
would not raise exception (skipping the code inside brackets).
So the question is: what is happening inside that if statement? maybe a hidden try-catch cast of left operand from bool? to bool with catch setting the result to false? or maybe right operand cast from bool to bool?? or something else?
See lifted operators in Nullable value types
I short, they are overloaded for comparisons like ==:
For the equality operator ==, if both operands are null, the result is
true, if only one of the operands is null, the result is false;
otherwise, the contained values of operands are compared.
So by comparing with true or false you can avoid handling the case that the nullable is null which makes the code more readable like in your example:
if (nullableVariable == true)
{
//some other lines of code
}
So whenever you compare(== or !=) a bool? with a bool the result is not a bool?(or null) but a bool with the rules described in the link above. That's why you can use it in the if.
As mentioned by others, the equality operators are lifted to the nullable equivalents.
There does seem to be slight differences in the way it is compiled. I'm not entirely sure why, but it may be to do with lack of compiler knowledge whether an operator is side-effecting for complex structs, whereas types like int and bool it knows what's going on.
Where A and B are nullables then,
A == B
This is compiled to the following for basic types like int:
(A.GetValueOrDefault() == B.GetValueOrDefault()) && (A.HasValue == B.HasValue)
And to this for more complex types:
(A.HasValue == B.HasValue) ? !A.HasValue || (A.GetValueOrDefault() == B.GetValueOrDefault())

Is there a conditional operator for setting a variable in C# to the value of another variable if the latter isn't null?

Something like the ternary operator (?:) or the null coalescing operator (??). It seems silly to me to take up two lines and be so wordy when the other operators exist.
EDIT:
Since it's requested, here's two possible examples of what I hope that I can find
var variable ?= mightBeNull;
or
var variable = mightBeNull != null ? mightBeNull
Really, it's either something that can be used to assign a value, if it's not null, to a variable or an If without an Else packaged nicely in an operator.
The ??= operator is coming to C# 8.
int? i = null; // i = null
i ??= 0; // i = 0
i ??= 1; // i = 0
// different ways of writing 'i ??= 0;':
i = i ?? 0;
if (i == null) i = 0;
So you want this?
if (other != null)
someVariable = other;
You could do the following, but I'd argue that the above is better due to clarity and possible side effects:
someVariable = other ?? someVariable;
The above might cause side effects if someVariable is a property and either the get or set can cause side effects; this shouldn't be important if your property follows the ordinary guidelines. Or, as Servy points out, even if it's a field, it could created different semantics in a multithreaded app. I should note that in the first example, you read other twice, which also has the potential for complexity to enter (though a smaller potential than the latter example).
I bet this is what you are looking for.
Let's say we have a function, myFunction that says whether the argument passed input is null or not. If input is null, it will return "Input is null!", else it will return "Input is not null".
This is the normal approach:
public String myFunction(string input) {
if (input == null)
return "Input is null!";
else
return "Input is not null";
}
And this is the other approach (What you are looking for):
public String myFunction(string input) {
return (input == null) ? "Input is null!" : "Input is not null";
}
It is called (?: conditional operator).
To assign a value to a variable only if it is not null, you would need to use an if. Neither the conditinal nor the null coalesce operators would do that.
if(somethingElse != null) something = somethingElse;
There is no specific operator in C# that does exactly this.
In Visual Studio 2015 C# there is a new operator called the Null-Conditional that does what you are asking. It is the ?. or ? operator.
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0]; // null if customers is null
int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null
Currently useable in previous versions of C# but not an operator but rather a one liner would be to use the ? : statement
?: operator
condition ? first_expression : second_expression;
AssingningTO = (someVar == null) ? null: someVar; // if null assign null ELSE assign someVar
AssingningTO = (someVar == null) ? String.Empth(): someVar; // if null assign empty string else someVar
Nullable types can represent all the values of an underlying type, and an additional null value.
http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx

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.

Negate the null-coalescing operator

I have a bunch of strings I need to use .Trim() on, but they can be null. It would be much more concise if I could do something like:
string endString = startString !?? startString.Trim();
Basically return the part on the right if the part on the left is NOT null, otherwise just return the null value. I just ended up using the ternary operator, but is there anyway to use the null-coalescing operator for this purpose?
You could create an extension method which returns null when it tries to trim the value.
public String TrimIfNotNull(this string item)
{
if(String.IsNullOrEmpty(item))
return item;
else
return item.Trim();
}
Note you can't name it Trim because extension methods can't override instance methods.
Not to spec: Not that I like it, but you could use:
string endString = (startString ?? String.Empty).Trim();
To spec, better as an Extension method like #Kevin's:
string endString = (startString == null ? null : startString.Trim());
string endString = string.IsNullOrEmpty(startString) ? startString : startString.Trim();
Though I've also gone the route of writing a string extension method called "safeTrim" which does what you're describing in one method instead of having to use this recipe every time. Check out Kevin's respone for the code.
EDIT: wow I had it all kinds of backwards, wrongly named variables and reversed ternary operators, all the more reason to write one extension method and code check it better than I did!
Starting with C# 6.0 (.NET Framework 4.6 / Visual Studio 2015) you can use null-conditional member access:
string? endString = startString?.Trim();
Sorry for the necromancy, but I was having this same problem and I solved this using a lambda operation. It isn't the prettiest, but it keeps my code succinct.
It's a shame C# doesn't support static imports or individual function imports, but anyway:
Define this function somewhere:
private static TResult N<TParent,TResult>(TParent parent, Func<TParent,TResult> operation) {
if( parent == null ) return default(TResult);
return operation( parent );
}
Then to use it in your example:
String endString = N(startString, s => s.Trim());
The N function returns null if the first argument is null, otherwise it will evaluate the specified lambda function with the value as the argument.
You can nest it, of course, like so. For example, to safely dereference a long chain, e.g.
String someValue = someObject.SomeProperty.SomeOtherProperty.SomeMethod().SomeFinalProperty;
if any of those properties or methods returns null then you have to insert null checks everywhere, or you could do this:
String someValue = N(N(N(N(someObject, o => o.SomeProperty), o => o.SomeOtherProperty), o => o.SomeMethod()), o => o.SomeFinalProperty);
As I said, it isn't the prettiest :)
You could simplify this by making N an extension method of System.Object, like so:
String someValue = someObject.N( o => o.SomeProperty ).N( o => o.SomeOtherProperty ).N( o => o.SomeMethod() ).N( o => o.SomeFinalProperty );
...which I think is a lot tidier.
Use
string endString = (startString ?? "").Trim();
This uses an empy string if startString is null. This, however, does not return null when endString is null.
Fast-forward to 2021:
10 years later startString?.Trim() is definitely the better option. And this does return null.
The following doesn't propagate null but it accepts null as a parameter and returns an empty string in that case.
using Microsoft.VisualBasic; // you need to add a reference to Microsoft.VisualBasic.dll
...
string endString = Strings.Trim(startString);
...
duck&run...
As as side note, if you're using .NET 4, there's a new convenient method String.IsNullOrWhiteSpace which you can use.

How-to: short-circuiting inverted ternary operator implemented in, e.g. C#? Does it matter?

Suppose you are using the ternary operator, or the null coalescing operator, or nested if-else statements to choose assignment to an object. Now suppose that within the conditional statement, you have the evaluation of an expensive or volatile operation, requiring that you put the result into a temporary variable, capturing its state, so that it can be compared, and then potentially assigned.
How would a language, such as C#, for consideration, implement a new logic operator to handle this case? Should it? Are there existing ways to handle this case in C#? Other languages?
Some cases of reducing the verbosity of a ternary or null coalescing operator have been overcome, when we assume that we are looking for direct comparisons, for example. See Unique ways to use the Null Coalescing operator, in particular the discussion around how one can extend the usage of the operator to support String.IsNullOrEmpty(string). Note how Jon Skeet is using the PartialComparer from MiscUtil, to reformat 0s to nulls,
Why is this possibly necessary? Well, take a look at how we write a comparison method for complex objects without any shortcuts (examples from the cited discussions):
public static int Compare( Person p1, Person p2 )
{
return ( (result = Compare( p1.Age, p2.Age )) != 0 ) ? result
: ( (result = Compare( p1.Name, p2.Name )) != 0 ) ? result
: Compare( p1.Salary, p2.Salary );
}
Jon Skeet writes a new comparison to fallback the equality case. This allows the expression to extend by writing a new specific method which returns null, allowing us to use the null coalescing operator:
return PartialComparer.Compare(p1.Age, p2.Age)
?? PartialComparer.Compare(p1.Name, p2.Name)
?? PartialComparer.Compare(p1.Salary, p2.Salary)
?? 0;
The null coalescing operator is more readable because it has two sides, not three. The boolean condition clause is separated into a method, in this case returning null if the expression must be continued.
What would the above expression look like if we could more easily put the condition in-line? Take the expression from PartialComparer.Compare which returns null, and place it in a new ternary expression which allows us to use the evaluation of the left-side expression, with an implicit temporary variable value:
return Compare( p1.Age, p2.Age ) unless value == 0
: Compare( p1.Name, p2.Name ) unless value == 0
: Compare( p1.Salary, p2.Salary );
The basic "flow" of an expression would be:
expression A unless boolean B in which case expression C
Rather than being an overloaded comparison operator, I suppose this is more like a short-circuiting inverted ternary operator.
Would this type of logic be useful? Currently the null coalescing provides us a way to do this with the conditional expression (value == null).
What other expressions would you want to test against? We've heard of (String.IsNullOrEmpty(value)).
What would be the best way to express this in the language, in terms of operators, keywords?
personally I'd avoid the short circuit from operators and just let the methods chain it:
public static int CompareChain<T>(this int previous, T a, T b)
{
if (previous != 0)
return previous;
return Comparer<T>.Default.Compare(a,b);
}
use like so:
int a = 0, b = 2;
string x = "foo", y = "bar";
return a.Compare(b).CompareChain(x,y);
can be inlined by the JIT so it can perform just as well as short circuiting built into the language without messing about with more complexity.
In response to your asking whether the above 'structure' can apply to more than just comparisons then yes it can, by making the choice of whether to continue or not explict and controllable by the user. This is inherently more complex but, the operation is more flexible so this is unavoidable.
public static T ElseIf<T>(
this T previous,
Func<T,bool> isOK
Func<T> candidate)
{
if (previous != null && isOK(previous))
return previous;
return candidate();
}
then use like so
Connection bestConnection = server1.GetConnection()
.ElseIf(IsOk, server2.GetConnection)
.ElseIf(IsOk, server3.GetConnection)
.ElseIf(IsOk, () => null);
This is maximum flexibility in that you can alter the IsOk check at any stage and are entirely lazy. For situations where the is OK check is the same in every case you can simplify like so and entirely avoid extensions methods.
public static T ElseIf<T>(
Func<T,bool> isOK
IEnumerable<Func<T>[] candidates)
{
foreach (var candidate in candidates)
{
var t = candidate();
if (isOK(t))
return t;
}
throw new ArgumentException("none were acceptable");
}
You could do this with linq but this way gives a nice error message and allows this
public static T ElseIf<T>(
Func<T,bool> isOK
params Func<T>[] candidates)
{
return ElseIf<T>(isOK, (IEnumerable<Func<T>>)candidates);
}
style which leads to nice readable code like so:
var bestConnection = ElseIf(IsOk,
server1.GetConnection,
server2.GetConnection,
server3.GetConnection);
If you want to allow a default value then:
public static T ElseIfOrDefault<T>(
Func<T,bool> isOK
IEnumerable<Func<T>>[] candidates)
{
foreach (var candidate in candidates)
{
var t = candidate();
if (isOK(t))
return t;
}
return default(T);
}
Obviously all the above can very easily be written using lambdas so your specific example would be:
var bestConnection = ElseIfOrDefault(
c => c != null && !(c.IsBusy || c.IsFull),
server1.GetConnection,
server2.GetConnection,
server3.GetConnection);
You've got lots of good answers to this question already, and I am late to this particular party. However I think it is worthwhile to note that your proposal is a special case of a more generally useful operation which I dearly wish C# had, namely, the ability to in an expression context, give a name to a temporary computation.
In fact C# has this operator but only in query comprehensions. I wish we had been able to add this as an operator in C# 3:
public static int Compare(Person p1, Person p2) =>
let ages = Compare(p1.Age, p2.Age) in
ages != 0 ?
ages :
let names = Compare(p1.Name, p2.Name) in
names != 0 ?
names :
Compare(p1.Salary, p2.Salary);
"Let expressions" are one of those expressions that are so useful, and found in so few languages, and I genuinely do not understand why language designers do not add it immediately in version one.
If C# had this feature then your proposed:
A() unless B() : C()
is simply
let a = A() in B() ? C() : a
which is hardly more difficult to understand, and bonus, you get to use a in expressions B() and C() if you like.
Let expressions can be emulated in any language that has lambdas; of course let x = y in z is simply (x=>z)(y), but there is no concise way to write that in C# either because C# requires a conversion to a delegate type on every lambda.
Incidentally, in Roslyn we do not represent temporaries as let-expressions, though we could. Rather, we go even one level below that and have a representation for "sequence of operations that might produce values, one of which will become the value of this expression". "let x = y in z" is simply the sequence "allocate x, x = y, z, deallocate x" where the third element is the value. And in the original pre-roslyn C# compiler we had internal operators "left" and "right", which were binary operators that took two expressions and produced either the left or right side, so we could generate ((allocate x) right ((x = y) right z)) left (deallocate x).
My point here is: we often get requests for bespoke language features with unusual punctuation, but it would in general have been better to implement the basic building blocks that you could build these operators out of in a natural way.
To place one proposed implementation away from a very verbose question, let's run with the unless keyword.
(expression A) unless (boolean B) <magical "in which case" operator> (expression C)
... would be all there is to it.
Boolean expression B would have access to the evaluation of expression A through the keyword value. Expression C could have the unless keyword in its expression, allowing for simple, linear chaining.
Candidates for the <magical "in which case" operator>:
:
|
?:
otherwise keyword
Usage of any symbols tend to diminish readability for the average developer. Even the ?? operator is not used widely. I, myself, do prefer to develop verbose code, but that I can easily read one year from now.
So a candidate for your :
expression A unless boolean B in which case expression C.
would be
expression A unless boolean B sothen expression C.
Although many people like me would still use:
if (B) {expression C;}
else {expression A;}
This comes in when you are developing a software with a big team, with different backgrounds, each one on the team master of one language, and just user of others.
More #ShuggyCoUk: Ah, I see that this might work for more than just comparisons? I haven't used C# 3 and extension methods, but I suppose you can declare, for my previous example, below, a
public delegate bool Validation<T>( T toTest );
public static T Validate<T>( this T leftside, Validation<T> validator )
{
return validator(leftside) ? leftside : null;
}
Followed by, per Skeet:
Validation<Connection> v = ( Connection c ) => ( c != null && !( c.IsBusy || c. IsFull ) );
Connection bestConnection =
server1.GetConnection().Validate( v ) ??
server2.GetConnection().Validate( v ) ??
server3.GetConnection().Validate( v ) ?? null;
Is this how that would work in C#? Comments appreciated. Thank you.
In response to ShuggyCoUk:
So this is an extension method in C# 3, then? Also, the result here is an int, not an arbitrary expression. Useful for overloading yet another comparison method. Suppose I wanted an expression for choosing the best connection. Ideally, I want something to simplify the following:
Connection temp;
Connection bestConnection =
( temp = server1.GetConnection() ) != null && !(temp.IsBusy || temp.IsFull) ? temp
: ( temp = server2.GetConnection() ) != null && !(temp.IsBusy || temp.IsFull ) ? temp
: ( temp = server3.GetConnection() ) != null && !(temp.IsBusy || temp.IsFull ) ? temp
: null;
Ok, so one could have a method
bool IsOk( Connection c )
{
return ( c != null && !(c.IsBusy || c.IsFull) );
}
Which would produce:
Connection temp;
Connection bestConnection =
( temp = server1.GetConnection() ) && IsOk( temp ) ? temp
: ( temp = server2.GetConnection() ) && IsOk( temp ) ? temp
: ( temp = server3.GetConnection() ) && IsOk( temp ) ? temp
: null;
But how would method chaining for comparisons work, here? I am pondering something which looks like:
Connection bestConnection =
server1.GetConnection() unless !IsOk(value) otherwise
server2.GetConnection() unless !IsOk(value) otherwise
server3.GetConnection() unless !IsOk(value) otherwise null;
I think that there are so far, hoops to jump through, if I want the result of a conditional to be an expression or result of a method which was in the original conditional.
I assume that the object returned by such methods will be expensive to produce, or will change the next time the method is called.

Categories

Resources