What is this operator, "??" [duplicate] - c#

This question already has answers here:
What do two question marks together mean in C#?
(19 answers)
Closed 5 years ago.
I'm on an upgrade project and recently began experiencing issues with the upgraded version of a DLL. I decompiled the original dll and found the following if statement:
if (fieldConfiguration == null && Context.ContentDatabase != null)
{
Item obj = Context.ContentDatabase.SelectSingleItem(
string.Format("//*[##templateid='{0}' and ##key='{1}']",
(object) TemplateIDs.TemplateField, (object) fieldName));
}
I then decompiled the upgraded version of the DLL and the statement was as follows:
if (fieldConfiguration == null && (Context.ContentDatabase ?? Context.Database) != null)
{
Item obj = Context.ContentDatabase.SelectSingleItem(
string.Format("//*[##templateid='{0}' and ##key='{1}']",
(object) TemplateIDs.TemplateField, (object) fieldName));
}
I was able to step through the code by decompiling the DLLs with dotPeek and using the dotPeek symbol server functionality. I can see that the code is failing when using the upgrade DLL because Context.ContentDatabase is null. What I don't understand is how that double ternary operator is evaluated. Could someone clarify for me what's going on there? It seems as though the creators of this assembly wanted a null check for Context.ContentDatabase but may have made a mistake. Thanks for the help!

Well yeah that looks like an error. The code is looking whether Context.ContentDatabase or Context.Database aren't null, and then continues to use the former, even if it was null.
The code should look like this:
var database = Context.ContentDatabase ?? Context.Database;
if (fieldConfiguration == null && database != null)
{
Item obj = database.SelectSingleItem(
string.Format("//*[##templateid='{0}' and ##key='{1}']",
(object) TemplateIDs.TemplateField, (object) fieldName));
}
Where it stores the database in a separate variable using the null-coalescing operator and then operates on that, if it isn't null.
So you should contact the team who provides this library and file a bug with them.

(Context.ContentDatabase ?? Context.Database) expressions end result is Context.ContentDatabase if Context.ContentDatabase is not null, otherwise it'll be Context.Database. The null-coalesce operator is a step forward to terse null checks.
Docs: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operator

Assuming Context.ContentDatabase and Context.Database are same types. The below code should work.
var contentDatabase = Context.ContentDatabase ?? Context.Database;
if (fieldConfiguration == null && contentDatabase != null)
{
Item obj = contentDatabase.SelectSingleItem(
string.Format("//*[##templateid='{0}' and ##key='{1}']",
(object) TemplateIDs.TemplateField, (object) fieldName));
}

Related

Check if child object value exists NullReferenceException

I'm pretty new to C#. While attempting to set a local variable value, I'm running into a NullReferenceException.
It appears that the Buyer object is null, which I'm assuming is why it can't figure out the Buyer.Username value. What I'm not sure about is how to check if Buyer is not null AND that the Buyer.Username has a non-null value (in the most simple way possible). Unfortunately, I'm using C# 7.3 which doesn't appear to have support for the ?? operator.
BuyerUserName = string.IsNullOrEmpty(model.Transactions[i].Buyer.Username) ? "" : model.Transactions[i].Buyer.Username
Both ?? and ?. were introduced in C# 6, so you can use them:
BuyerUserName = model.Transactions[i].Buyer?.Username ?? string.Empty;
But even without that, there is nothing wrong with taking more than one line to do something, and you could just use an if statement:
var buyer = model.Transactions[i].Buyer;
if (buyer != null && buyer.Username != null)
BuyerUserName = buyer.Username;
else
BuyerUserName = string.Empty;

Why does C# compiler thinks this nullabale reference can be null?

I have this code where the compiler says that myObj in ValidateMyObj(myObj) may be null.
Since it has to be not-null for string.IsNullOrEmpty to return false and enter the condition, how can it consider it could be null?
But most of all, how can it then consider that it cannot be null in myObj.Exists?
var myObj = myObjCol.FirstOrDefault(x => x.Member);
if (!string.IsNullOrEmpty(myObj?.StrProp))
{
ValidateMyObj(myObj);
if (ViewBag.IsValid)
myObj.Exists = true;
}
Edit: Playing with explicit null-check
Simply adding the explicit null-check gives the same behaviour:
var myObj = myObjCol.FirstOrDefault(x => x.Member);
if (myObj != null && !string.IsNullOrEmpty(myObj?.StrProp))
{
ValidateMyObj(myObj);
if (ViewBag.IsValid)
myObj.Exists = true;
}
this compiles to (according to the ILSpy decompiler when deactivating the decompilation of the ? operator)
MyObjType myObj = myObjCol.FirstOrDefault(x => x.Member);
if (myObj != null && !string.IsNullOrEmpty((myObj != null) ? myObj.StrProp : null))
{
ValidateMyObj(myObj);
if (ViewBag.IsValid)
myObj.Exists = true;
}
On the other hand, if I then remove the null-conditional operator, then the squiggly line disapears.
var myObj = myObjCol.FirstOrDefault(x => x.Member);
if (myObj != null && !string.IsNullOrEmpty(myObj.StrProp))
{
ValidateMyObj(myObj);
if (ViewBag.IsValid)
myObj.Exists = true;
}
In fact, it also disapears if I remove the explicit check and the null-conditional operator nor does it give one on the argument passed to ÌsNullOrEmpty`:
var myObj = myObjCol.FirstOrDefault(x => x.Member);
if (!string.IsNullOrEmpty(myObj.StrProp))
{
ValidateMyObj(myObj);
if (ViewBag.IsValid)
myObj.Exists = true;
}
If I got this right then i think it is because the IsNullOrEmpty is refering to the StrProp but the warning targets the myObj
Clarification:
if myObj is null then there isn't a StrProp to check for
The null-state analysis of the C# compiler tries to keep track of the null-state of every variable based on the context where it is used.
The null-state might be:
The value is known to be null.
The value is known to be not null.
The null-state is unknown (maybe-null).
After the assignment var myObj = myObjCol.FirstOrDefault(x => x.Member); myObj is in the maybe-null state (this actually depends on the framework – see below).
The call to string.IsNullOrEmpty doesn't change the null-state. The string.IsNullOrEmpty method is just an ordinary method. Without extra knowledge the compiler doesn't know anything about the null-state of the parameter.
It turns out that in .NET 6 the compiler gets this extra help. In .NET 6 the signature of that method is:
public static bool IsNullOrEmpty([NotNullWhen(false)] string? value);
In .NET Framework however the signature is:
public static bool IsNullOrEmpty(string value);
The NotNullWhen attribute tells the compiler that the argument passed to string.IsNullOrEmpty is not null when the method returns false. Therefore in .NET 6 you don't get any warnings in your original code because the compiler changes the null-state to not-null inside the if-block. In .NET Framework 4.8 (or earlier) it can't do that so the null-state inside the if-block is the same as outside.
Surprisingly after adding the explicit null check for myObj the squiggly line doesn't go away.
if (myObj != null && !string.IsNullOrEmpty(myObj?.StrProp)) { ... }
is equivalent to
if (myObj != null)
{
// null-state of myObj is not-null
if (!string.IsNullOrEmpty(myObj != null ? myObj.StrProp : null))
{
// the second test changed the null-state of myObj to maybe-null
}
}
When you now remove that second test the null-state doesn't change and the warning goes away.
The framework also influences how the return value of the FirstOrDefault method is treated.
Right at the beginning you have:
var myObj = myObjCol.FirstOrDefault(x => x.Member);`
Obviously this should set myObj to the maybe-null state and should give a warning when you then dereference the variable without checking for null:
if (!string.IsNullOrEmpty(myObj.StrProp)) { ... } // should warn: Dereference of a pssibly null reference
It seems that it doesn't do that when you are on .NET Framework. But it does when you are on .NET 6.
This can be explained when you look at the history of C# and .NET.
C# 8 was the first version to support nullable reference types. It was released shortly after the last version of .NET Framework (4.8).
In .NET Framework the signature is:
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
In .NET 6 it is:
public static TSource? FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
This means that the nullability context is unclear when you call FirstOrDefault<T> on .NET Framework but it is clear on .NET 6.
As far as I am aware the C# compiler team has decided not to warn when the context is unclear because that would give too many false warnings and would annoy too many people.
Having said that: If you want more reliable nullability analysis you should use a version of the framework which is fully null-aware.

Non-static method requires a target. cant find an answer that seems to work

Every post I have found suggests that this happens when there is a null value. I have tried examples such as one found here but no matter what I seem to try I still end up with the same error message.
Does anyone have any idea of what the case could be?
var aaresults1 = (from a in db.AAs
where a.AAID == aaid.AAID & a != null
select a);
Reading through other StackOverflow posts about this error, it appears to happen when a where clause refers to a value that is null. Based on that, I'm guessing that your aaid object is null when you run this.
var aaresults1 = db.AAs.AsQueryable();
if(aaid != null)
{
aaresults1 = aaresults1.Where(a => a.AAID == aaid.AAID);
}

Check All Child Properties For Null in C#

I have the following line of code below. Is there a method that can check team, DivisionTeam, Team, Coordinator, Profile, Address, and the last property StateRegion for null instead of doing it for every property?
if(team.DivisionTeam.Team.Coordinator.Profile.Address.StateRegion != null)
Currently in C#, you can't, you have to individually check each property for null.
May be you are looking for ".?" operator, but its not there in C# 4.0, Check out this post and the response from Eric Lippert: Deep null checking, is there a better way?
You should check the following article: Chained null checks and the Maybe monad. This is, IMO, the cleanest way to actually "do" what you are asking for.
And, no, there is no inbuilt way in C# to do this directly.
In C# 6.0 you can do it in just one string:
var something = team?.DivisionTeam?.Team?.Coordinator?.Profile?.Address?.StateRegion;
Check this article for further reading: null-conditional operator.
Here is a sample
private bool IsValidTeam(Team team)
{
bool result = false;
if (team != null)
if (team.DivisionTeam != null)
if (team.DivisionTeam.Team != null)
if (team.DivisionTeam.Team.Coordinator != null)
if (team.DivisionTeam.Team.Coordinator.Profile != null)
if (team.DivisionTeam.Team.Coordinator.Profile.Address != null)
if (team.DivisionTeam.Team.Coordinator.Profile.Address.StateRegion != null)
result = true;
return result;
}
Check my answer here:
https://stackoverflow.com/a/34086283/4711853
You could simply write a small extension method, which afford you to write chained lambda like this:
var value = instance.DefaultOrValue(x => x.SecondInstance)
.DefaultOrValue(x => x.ThirdInstance)
.DefaultOrValue(x => x.Value);

What is good practice for null reference checks? [duplicate]

This question already has answers here:
Best and fastest way to check if an object is null [duplicate]
(6 answers)
Closed 9 years ago.
What is the most efficient way to check for null references on objects? I have seen various code samples that have different ways of checking so of the following which is the most efficient or the one that it is considered best practice to use?
Object.ReferenceEquals(item, null)
item == null
item != null
Object.Equals(item, null)
thanks
Object.ReferenceEquals(item, null) compare references and equals to item == null.
Object.Equals(item, null) compare references for reference types and bitwise for value types, but in reflector it's equal to (item == null) || ((item != null && null != null) && item.Equals(null)).
item != null code not always equals to !(item == null), but of course result should be equal.
item == null code not equals to null == item, it's similar to typeof(item).Equals(object) and object.Equals(typeof(item)) method calls.
It differ because you can override !=, ==, Equals.
Use methods with known implementation, null == item is better to code, but harder to read.
Object.ReferenceEquals(null, item) may be faster or not.
P.S. use string.IsNullOrEmpty(item) too
For comparing to null, I'd use == or != always, because for null it should always give the same result as ReferenceEquals and Equals anyway (so no need for the extra code).
Edit: It's true that == could be overridden to give a wrong result for null (i.e., true) but that means the override is buggy. To make the code readable I would stick with == and !=.
Updated answer
As of C# 7.0 is you can use:
item is null
should be the simplest and most foolproof way. It's same as ReferenceEquals check.
Old answer:
1)
Object.ReferenceEquals(item, null)
This is a good way. Not as concise as I would love, but still great and tells u the intent exactly.
2)
item == null
item != null
There is nothing wrong with this (which is the most elegant) if you are sure == and subsequently != is overloaded correctly. Its easy to write (overload) bad equality operators (and often done). But the real trouble is when you are trying to overload == operator in a class (lets say of value semantic). You cant use == for null checks inside == overloading function of the class since that will cause an infinite recursion. To have one consistent style, I rely on something else.
3)
Object.Equals(item, null)
Again it internally does a ReferenceEquals so there is not much point, but if it semantically makes more sense to you, then go with this.
4)
My approach is to do
(object)item == null
upon which I'm relying on object's own equality operator which can't go wrong. Not so readable so I just wrap in a custom extension method and an overload:
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null;
}
public static bool IsNull<T>(this T? obj) where T : struct
{
return !obj.HasValue;
}
It makes more sense since I will need to check against DBNulls too often. So now I have one consistent style all over!
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null || obj == DBNull.Value;
}
(Do not take off the (object) casting as that's what will prevent infinite recursion when overloading == as stated before)
Additionally the constraint prevents IsNull on value types. Now its as sweet as calling
object obj = new object();
Guid? guid = null;
bool b = obj.IsNull(); // false
b = guid.IsNull(); // true
2.IsNull(); // error
I also have found (object)item == null is very very very slightly faster than Object.ReferenceEquals(item, null) or object.Equals(,) for that matter, but only if it matters (I'm currently working on something where I've to micro-optimize everything!).
To see a complete guide on implementing equality checks, see What is "Best Practice" For Comparing Two Instances of a Reference Type?
As an extra, don't forget code contracts in .NET 4.0!
System.Diagnostics.Contracts.Contract.Requires(item != null);
Which is not only nice and clear, but allows compile time checking. See Code Contracts in msdn.
ReferenceEquals is equivalent to (object)o1==(object)o2. It may be faster than o1==o2 if the equality operator is overloaded. Object.Equals is probably a bit slower.
The difference between == and != isn't performance, but how your program should look like. They can be a bit slower if the == and != operator are overloaded.
But I don't think the performance difference between them matters at all. I'd choose the one that's easiest to read. And that's usually == or !=.
If I throw an exception I usually use == as in:
if(o == null)
throw new ...;
If null results in a no-op then usually != is appropriate
if(x != null)
{
...
}
I always use
item != null
but this is harder to read than
item == null
Object.ReferenceEquals is used to check whether two objects are the same instance.
First 2 are the same effectively.
The last however does not only do a reference check, and should not be used for null checking.

Categories