-
@rickardp commented on Wed Nov 04 2015 Consider the following loop:
which will default to an empty enumerable in case One way this can be solved right now is to create an extension method, e.g.
which is not bad at all actually (though still not built into LINQ AFAIK), but I think that it would be better still if there was a way similar to the null-propagation operators (
I understand that constructing the syntax for a solution to this problem can be tricky, but I think it is at least worth considering since I believe the case is quite common (I find it a lot more common than the null-propagation indexer operator in my code). Why using null at all and not empty enumerables everywhere? One example where I find the scenario common is in serialization of objects, where empty collections are omitted and should therefore semantically be identical to null. Since @dsaf commented on Thu Nov 05 2015 The question mark should probably be next to enumerable rather than the keyword? Although there might be some ambiguity I guess... foreach (var item in myEnumerable?)
{
} @vladd commented on Fri Nov 06 2015 Well, in my opinion the empty enumerable should be distinguishable from (If you encounter often @rickardp commented on Sat Nov 07 2015 @vladd I think your point is very valid, and in this way C# differs from, for example, Objective-C where a The reason that I think this would be helpful is not helping to deal with broken APIs but rather interaction with dynamic languages and objects, generics where
Then, to handle the case where the user might have omitted the
I tend to see this pattern a lot (in my code and others') especially when it comes to dealing with data serialization and interaction with external programs. For LINQ and index operators we already have null propagation that helps with null checking. I think it is still worth considering some kind of symmetry with @bbarry commented on Sat Nov 07 2015 I don't know if it is particularly useful but you can always do:
or:
@aluanhaddad commented on Fri Nov 13 2015 @rickardp This is interesting. Most of the time, returning null for collection types likely indicates a badly designed API. The serialization point however, is worth examining in more detail. I also run into this issue/question regularly. I think the correct way to handle it is often to customize the serialization/deserialization to impose the semantics you desire. If you are writing the serialized classes, you can initialize collection properties to empty. That said, the question of whether empty and @rickardp commented on Sat Nov 14 2015 @aluanhaddad Good points! Though I often find myself in a situation where this design is out of my control. Some code may be generated, or some tradeoffs might have been done for performance reasons (e.g. large data sets on mobile devices), and in any case that piece of code might not be maintained by me. IMHO one of the greatest strengths with C# is its ability to deal with real-world situations while still keeping your own code clean and maintainable. Even as we are embracing the semantic difference between @aluanhaddad commented on Sat Nov 14 2015 While the I think that the combination of the At any rate, your extension method public static IEnumerable<T> EmptyIfNull(this IEnumerable<T> enumerable) {
return enumerable ?? Enumerable.Empty<T>();
} actually handles the uncertainty quite well without the need for additional syntax. @yaakov-h commented on Sat Nov 21 2015 Considering how often something like this is needed, what's the value of returning @paulomorgado commented on Mon Nov 30 2015 @yaakov-h, the difference is the difference between and empty box (empty collection) and no box ( If you have no box, you can assume you have no items. But that's a particular interpretation of what you having no box means. There might be a box but hasn't been handed to you yet. You cannot tell the color of a box if you have no box. Nor its size/capacity. You can fill an empty box, but you can't fill no box. @NickCraver commented on Sun May 29 2016 The confusion here I see is for new devs hitting null reference exceptions here. It's just not expected, they don't know that In almost all null cases, I simply don't want to loop if there's nothing to loop over. Today, that's a wrapper: if (myCollection != null)
{
foreach (var i in myCollection) { }
} It'd be nice to have a cleaner syntax for this all around, as we have tons of these I think we can do something here to save a lot of wrapper code, though where the best place for a @gafter commented on Sun May 29 2016
It sounds like @paulomorgado commented on Sun May 29 2016 @gafter, I think @NickCraver is saying that the But that would be a breaking change. @NickCraver commented on Mon May 30 2016 @paulomorgado Oh no - I'm saying @HaloFour commented on Mon May 30 2016 public static class EnumerableExtensions {
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> enumerable) {
return (enumerable != null) ? enumerable : Enumerable.Empty<T>();
}
} @paulomorgado commented on Mon May 30 2016 @NickCraver, that was my understanding, but didn't want to open the can of worms of @HaloFour, I still operate under the premisse that extension methods should look and behave like instance methods. @NickCraver commented on Mon May 30 2016 @paulomorgado none of those constructs suffer from this issue, nor does @aluanhaddad commented on Mon May 30 2016
You
I think the problem is that the error message is expressed in terms of the compiler implementation, not that there is an error. Imagine if the error message read "Unable to enumerate null", wouldn't that clear things up? If methods ignore the nullness of the enumerables they receive, merging the concept of null with empty, they are likely to propagate null in their return values. I think that would be harmful. Everyone would use the hypothetical new nullsafe foreach everywhere. @NickCraver commented on Mon May 30 2016
Yes, if we want to define hundreds of extension methods. I was specifically talking about the generic extension methods proposed earlier, the only reasonable thing that may be added in almost all cases. I agree the error message isn't obvious, and clearing it up would help, but it still doesn't address the usability and verbosity issue of wrapping everything in I don't believe this enables any better or worse behavior than today's verbose method. It simply allows developers to do what they want with less syntax, exactly as
Two things here:
@HaloFour commented on Mon May 30 2016
That's your decision, but my code is perfectly legal. It's pretty convenient to be able to invoke extension methods off @yaakov-h commented on Mon May 30 2016
Please explain which IL opcodes the C# compiler emits that causes this. My understanding is that NullReferenceException is the CLR's reinterpretation of a low-address access violation, and is not part of C#.
@HaloFour commented on Mon May 30 2016 C# always uses https://blogs.msdn.microsoft.com/ericgu/2008/07/02/why-does-c-always-use-callvirt/ If C# were to instead use the @aluanhaddad commented on Mon May 30 2016 @NickCraver First of all I did not mean to come off as dismissing the value of returning With regard to performance, I think it is valid but, as @gafter pointed out, methods that return With regard to extension methods, I'd be curious to see how many collection types you would need to define an extension method for. Hundreds does sounds very painful, but that is a lot of very specific types to be returning, especially if they are mostly used with
Well, all of my evidence is anecdotal, and thus should be disregarded, but I know many programmers who advocate defensive programming at the point of use. In other words, they are not confident in the API contract or it is insufficiently specified. In fact, it's been suggested to me that I should check Anyway, if your code base is full of if(values != null)
{
foreach (var value in values) { ... }
} I would assume you want to replace them all with Edit: fixed formatting. @NickCraver commented on Mon May 30 2016 @aluanhaddad How do you see this as any different than Would I use As for I think the "programmers will do X" argument is moot in either case. If the argument is "they'll just use @aluanhaddad commented on Mon May 30 2016
@NickCraver I certainly did not mean to come off as accusatory. I apologize. I do think in general that it's a poor practice to return null for values of type @NickCraver commented on Tue May 31 2016 For Also what about types that aren't returned at all? In razor views for example you're rendering the output and we have to put these To be clear: I'm not advocating specifically for @markrendle commented on Tue May 31 2016
@aluanhaddad commented on Tue May 31 2016
I generally return these types through interfaces like @markrendle I do find that the syntax @NickCraver commented on Tue May 31 2016 @aluanhaddad The "why?" for most of those is you're making a lot of assumptions about a codebase based on personal experience, which we all do. We only know what we've seen. However, you must realize many people don't use those interfaces, don't want to cast as those interfaces, and all of that complicates code in other ways.
No...I wouldn't. That's the entire point. I want to say "if null, skip it", that's what this entire issue is about. Also don't assume read-only behavior, that's a bad assumption. Language features and constructs cannot make assumptions like this, they have to handle the widest variety of cases and throw warning or errors for all the rest. In general most comments here ignore performance. They miss the point of not wanting to call Why not use @ghost commented on Tue May 31 2016
|
Beta Was this translation helpful? Give feedback.
Replies: 6 comments
-
It would be very helpful to have a syntax like this:
As it would make code with In some solutions it's not possible to initialize all collections. |
Beta Was this translation helpful? Give feedback.
-
I was going to object, but while trying to see it from the other side I realized that people will still default to non-null-safe |
Beta Was this translation helpful? Give feedback.
-
@jnm2: I +1'd your +1. |
Beta Was this translation helpful? Give feedback.
-
Voteception 😆 |
Beta Was this translation helpful? Give feedback.
-
Hi All, |
Beta Was this translation helpful? Give feedback.
-
See discussion in #1081. With the new collection expressions feature being worked on for C# 12, there will be a new minimal and efficient syntax: foreach (var item in myEnumerable ?? []) |
Beta Was this translation helpful? Give feedback.
See discussion in #1081.
With the new collection expressions feature being worked on for C# 12, there will be a new minimal and efficient syntax: