3 ms·
Isn't this more confusing? Because it skip the code if the value is null and I don't think it is normal to follow the flow assuming nothing has happened.
by wslh 1y ago
Isn't this more confusing? Because it skip the code if the value is null and I don't think it is normal to follow the flow assuming nothing has happened.
- cjbgkagh 1y agoIt’s for the use case where they’d skip it anyway so that would be intended behavior.
- accrual 1y ago> I don't think it is normal to follow the flow assuming nothing has happened. I think it is for situations where the programmer wants to check a child property but the parent object may be null. If the parent is expected to be null sometimes, the syntax lets the programmer express "try to get this value, but if we can't then move on" without the boilerplate of explicitly checking null (which may be a better pattern in some cases). It's sort of like saying: - Get the value if you can, else move on. We know it might not be there and it's not a big deal. v.s. - The value may not be there, explicitly check and handle it because it should not be null.
- BoiledCabbage 1y agoYour summary is almost correct but replace where you used "get" with "set".
- accrual 1y agoThanks! Yes, mistake on my part.
- electroly 1y agoThat's already the case for the null coalescing operator when it ends in a method call: the method call is skipped if the base is null. For instance, we can invoke event handlers with "myEvent?.Invoke(...);" and the call will be skipped if there are no event handlers registered, and this is the canonical way to do it.
- gus_massa 1y agoFrom the article: > If config?.Settings is null, the assignment is skipped. If the right hand expression has side effects, are they run? I guess they do, and that would make the code more predictable.
- Izikiel43 1y agoFrom the article as well: Side-Effect Prevention When a null-conditional statement assignment is evaluated, the right-hand side of the expression is not executed unless the left-hand side is defined.
- gus_massa 1y agoThanks. I missed it. I really dislike that, because it hides the control flow too much. Perhaps I'm biased by Racket, where it's easy to define something weird using macros, but you should not do unexpected weird things. For example you can define vector-set/drop that writes a value to a position of a vector, but ignores the operation when the position is outside the vector. For example (vector-set/drop v -2 (print "banana")) With a macro is possible to skip (print "banana") because -2 is clearly out of range, but if you do that everyone will hate you.
- ygra 1y agoI think in the context of C# this is not exactly unexpected since there are various operators that apply conditional execution (and evaluation) to parts of an expression. All of them start with ?, though (? :, ??, ?., ?[], ??=), so except for casts to nullable types, every question mark in an expression signals that control flow is about to happen and it's been that way in C# for quite a while.
- gus_massa 1y ago[Too late, sorry for the delay, but I had to think about it.] That ooks like a good reason. Looking at https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator https://learn.microsoft.com/en-us/dotnet/csharp/language-ref... , the magic is in the LHS or the RHS, and in ??= the magic is explicitly in the connection. Here, IMHO, the problem is that the magic jumps from one side to the other. Anyway, I don't use C#.
- alkonaut 1y agoIt kind of is more confusing because I always imagined the RHS to be evaluated first in an assignment, before the target is evaluated. The motivation is that you don't want the side effects in some cases like GetNextId() but I think it's still strange. I hacven't thought deeply about it but i _think_ I'd rather keep the intuitive right-hand-first evaluation and explicitly have to use if (..) in case I have a RHS whose side effects I need to avoid when discarded.