foreach? #1081
Replies: 47 comments 60 replies
-
Not as concise, but IEnumerable<object> Source = null;
foreach(var item in Source ?? Enumerable.Empty<object>()){
//This won't cause an error.
} |
Beta Was this translation helpful? Give feedback.
-
usually I throw exception if source is null but sounds nice. |
Beta Was this translation helpful? Give feedback.
-
I have an extension method that is simply MgSam's code, so I do:
(*nix people will recognize This change wouldn't be a big win but I do it often enough that I wouldn't say no to a |
Beta Was this translation helpful? Give feedback.
-
I'd hate to see a language construct that encourages people to conflate 'null' and 'empty' worse than they already do. Some people would see it as a "safer" foreach and use it defensively, not realizing that the NRE was actually better at preventing state corruption. (Always fail as early and as loudly as possible when the programmer's assumptions are violated- that's never a recoverable scenario.) Far better still, ArgumentNullException or a separate code path to deal with the separate semantics. If 'null' and 'empty' happen to be semantically equivalent in a certain case, make that explicit using |
Beta Was this translation helpful? Give feedback.
-
@jnm2 alright then, how does |
Beta Was this translation helpful? Give feedback.
-
@jnm2 there is only so much benefit to catering to green devs, when it is at the expense of everyone else. |
Beta Was this translation helpful? Give feedback.
-
I disagree. I've used several languages that are lenient with nil-like constructs, and it honestly feels fine to me when I use them. For better or worse, nulls permeate the entire ecosystem, and making them painful to deal with just means pain and aggravation when coding. For example, before That said, for this specific case, it does seem like there are acceptable existing workarounds. So my support of this particular situation is pretty low.
This doesn't have anything to do with devs being green or not. It has to do with the pervasiveness of 'null' and the cost of the excess ceremony necessary to deal with it. It was precisely this that led to the introduction of things like the null-propagation operator, and it's why there has been so much effort in C# 8 toward better analysis and exposure of null handling. Better handling of null is a significant feature for most C# devs, not just 'green' ones. |
Beta Was this translation helpful? Give feedback.
-
This is only true if you equate null with state corruption. Whereas, for an enormous number of apis and domains, it's a completely legal and expected value representing non-corrupt state. This is the crux of the problem. There is no one true ideology around 'null'. At least not in .net/c#. And even if we could pick an ideology that people liked for it, it wouldn't likely never get enough widespread adoption until we got to a point of everything being rewritten (at which point, we'd likely be using a different language anyways). The reality of the situation is that null exists. Is here to stay. And is enormously pervasive. We can't avoid any of that, or wish it away. As such, the language embraces that and accepts that being opinionated against that fact only serves to cause people more pain than good. It's also why, when we have accepted and worked to improve things in this area, the response has been nearly universally positive, with huge adoption across the ecosystem of these new constructs due to their value and convenience so outweighing these sorts of concerns that have been raised. |
Beta Was this translation helpful? Give feedback.
-
I do not equate null with state corruption. Nothing could be further from accurate. You could argue that |
Beta Was this translation helpful? Give feedback.
-
The line is already blurred, you can't un-blur it. I'd even argue that the blurriness necessary: .NET putting everything on the heap makes |
Beta Was this translation helpful? Give feedback.
-
I disagree, purely because (IMO), the thought experiment has been tried elsewhere and i've personally not found it to be an issue. Indeed, the blurring of the lines is what transforms it from a "pit of failure" to a totally fine programming paradigm :) In other words, it's precisely because null has to be handled so differently that it becomes a pit of fail. |
Beta Was this translation helpful? Give feedback.
-
Note: i don't forsee a lot of value coming from a huge back and forth on this :) I understand and can respect your position. Needless to say, i think making null handling more pleasant is valuable. but i also think the primary cases have already been handled well, and not much more work here is necessary at the language level. (Although, i do really think an |
Beta Was this translation helpful? Give feedback.
-
How can the follow do anything but fill you with joy? 😆 foreach (var item in Source is {} source ? source : Enumerable.Empty<object>())
{
//This won't cause an error.
} |
Beta Was this translation helpful? Give feedback.
-
What's the actual motivation for this?
I'm mostly in agreement with @jnm2 - there's a big difference between "this box has no items in it" and "there is no box". Null may be pervasive and here to stay, but that doesn't mean we should be using it everywhere, either. |
Beta Was this translation helpful? Give feedback.
-
What's the argument for not doing that? It seems reasonable to me. Note: this is one of those areas where the language/APIs incestuously impact each other. If, for example, the language had been null-tolerant here from the beginning (like you see in some other languages), then it would likely be the case that many APIs would use null routinely for collections. But, it doesn't, so it's less common.
That's domain specific. For many domains it suffices to mean "i don't have any items". This is why, for example, APIs like "string.IsNullOrEmpty" exist. Certainly, one could make the same argument "there's a big difference between no string and an empty string", and that's certainly true some of the time. But for a large set of cases, it's not actually a big difference at all. Given that .net has not at all really pushed that there's deep difference, and given that many out there are fine conflating, and given that other languages/domains certainly do this sort of conflation, i don't think it's reasonable to state that everyone has to think there is a large difference here. Indeed, as i mentioned earlier, i think one of the huge pain points around null is precisely that it blows up on you in domains where people don't need or want it to blow up. For example, when i did Objective-C development, nil wasn't really painful. That's because the majority of the language, APIs, and patterns worked well with it. As such, coding was pleasant without having to continually think about hte distinction, and without having to worry about code blowing up as much as i need to with .Net/C#. It's not wrong to want to move toward patterns that try to remove null entirely, but it's also not wrong to try to make the experience better when working in domains where null is common. |
Beta Was this translation helpful? Give feedback.
-
@huysentruitw if(source != null)
foreach (var item in Source) {...} |
Beta Was this translation helpful? Give feedback.
-
because of nesting of course. we also didn't need |
Beta Was this translation helpful? Give feedback.
-
But your syntax is no more concise, and is adding a completely new syntactic structure to the language. |
Beta Was this translation helpful? Give feedback.
-
But you don't have to explain anyone what it does... |
Beta Was this translation helpful? Give feedback.
-
Neither do you have to explain an if statement to anyone. |
Beta Was this translation helpful? Give feedback.
-
And we're back to #1081 (comment) |
Beta Was this translation helpful? Give feedback.
-
What I'm saying is |
Beta Was this translation helpful? Give feedback.
-
I would say that when would avoid an extra nested scope, so it is better than if.... |
Beta Was this translation helpful? Give feedback.
-
Then: Do we need some syntactic sugar for |
Beta Was this translation helpful? Give feedback.
-
I don't want to nitpick here, but (Another use case stems from the fact that it can be abused for side-effects in the Note that this is not intended as a counter-argument of conditional foreach... |
Beta Was this translation helpful? Give feedback.
-
Another alternative:
|
Beta Was this translation helpful? Give feedback.
-
Why not use the bang operator as an explicit declaration "it's not null or it should be empty" foreach(var item in Source!.Where(n => n.Value == 1)){
//This won't cause an error.
}
foreach(var item in Source!){
//This won't cause an error.
}
foreach(var item in Source?.Where(n => n.Value == 1)!){
//This won't cause an error.
} |
Beta Was this translation helpful? Give feedback.
-
I'm baffled why anyone would oppose this. The arguments against it seem to be nothing but pedantic and fall apart when you cosnider that I would fully support simply changing the behavior for |
Beta Was this translation helpful? Give feedback.
-
I'm really surprised that \e was accepted as a QOL enhancement but this was not. This seems much more useful to many more situations than \e. |
Beta Was this translation helpful? Give feedback.
-
The nitpicking about not confusing null and empty seems unreasonable when ?. ?? ??= are all in the language. Null forgiveness is a clearly established pattern now that is used everywhere, and the lack of foreach? just seems like an inconsistency. "This object may or may not have a value, and I want to use it" is hardly a narrow use case. If anything, it seems to me having this operator would actually help establish a distinction, because it would let you use both null and empty collections without inconveniencing the people who actually want to use the values contained in them. |
Beta Was this translation helpful? Give feedback.
-
It would be great to have a foreach? construct that would skip if the enumerable was null.
Beta Was this translation helpful? Give feedback.
All reactions