✅ `??=` and `??`
This question may not fit here because it is not a question about C# but more about why it is implemented in such a way, but I'll ask anyways:
Why is
item ??= item2
implemented as
instead of
?
The cast makes it so if the ==
operator is changed by the class, it will not use said operator, instead using the default ==
operator of object
.
This makes it so that in unity for example, where the ==
operator is changed by all unity objects, the ??=
operator cannot be used.
My other question is, does the ??
operator also cast to object
before null checking, or does it use something else completely, like pattern matching? I've used https://sharplab.io to see the lowering of ??
, but it doesn't appear to be lowered.37 Replies
how are you testing this?
i don't see a cast being done
The exact code I used to test this is
I used
if (inst == null) ;
to check if there is maybe a problem with my code, but the result is that it is only logged once (that once being this check).What's the point of that if?
as for sharplab.io, this is the result I get
https://discord.com/channels/143867839282020352/1053717640025210892/1053718999537557574
I would expect this code to output
ClassThingie equality operator called.
thrice, or at least twice if ??
uses pattern matching, but it's only printed oncei can't put it into words, but this is pretty much bogus
??
checks if (thing is null) { }
there's nothing else to it
all it checks is whether what's passed exists at all
there is no "equality" being checkedwhile that's the answer of my second question, it doesn't explain why
??=
does a castexactly so it doesn't call the equality operator of the class
because there is no. equality. being checked.
nothing is "equal" to null
can't be equal to something that doesn't exist, doesn't even have a concept of a type
unity seems to disagree then?
because they're fucking braindead
(no offense of course)
unity's implementation of almost everything is a complete mistake
they took the concept of "null equals false" from c++ (which is where their engine source code resides), and incorrectly implemented that into their c# API
which is absolutely asinine
a null value cannot equate to false
Okay, so the simple answer is just, don't use
??=
and ??
with unity.unfortunately
gotcha
thanks for your help!
the reason "null equals false" in lower level languages like C, C++, Python (unfortunately) is because they're comparing the pointers
and a null pointer evaluates to 0
and 0 evaluates to false
a non-zero value evaluates to true
yeah
so yes, unity completely fucked up when making an implicit bool operator for
UnityObject
that equates to false
when an object is nullyou should be able to use the implicit bool conversions in Unity, or just check for null
obj ? whenNotNull : whenNull
this should workIt doesn't
worth adding that
item is null
also does that same sort of object cast, ignoring any ==
overloads, because sometimes you want to make sure not to use overloaded operators for null checksIt does the same thing as ??
There is no cast involved
there is though?
No there isn't
IDK if there is one but it's as if there is one anyway, just pointing out that it's common to want to skip the overloads on null checks
That may be how the decompiler chooses to represent it when going back to C#
But it's not what happens in il
https://ericlippert.com/2013/05/30/what-the-meaning-of-is-is/ here's a long post about why
is null
is different from == null
which may explain why ??
works like the formerericlippert
Fabulous adventures in coding
What the meaning of is is
Today a follow-up to my 2010 article about the meaning of the is operator. Presented as a dialog, as is my wont! I’ve noticed that the is operator is inconsistent in C#. Check this out: strin…
And yes, unity does bad things like overloading == so null is weird for them
I get why they did it, but it didn't help their users wrt this type of thing
a bit misleading by sharplab then, or by decompilers, or whichever
It's a reasonable way to represent in C#
But when you look at the il, you'll see no casts
Think about it this way: reference conversions (such upcasting a class) mean nothing. They tell the compiler things, but absolutely nothing needs to happen at runtime
The only time they matter is when they can't be proved at compile time, such as downcasts
so then, what is the reason for the operator not to be executed?
actually, i guess a null check is indeed entirely different
The == operator? That's not how any of the null-conditional operators are defined
isn't it just like a
cmp
against 0
or somethingThey check for null, and only null
mh, yeah
this, basically
Correct
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.