The List Best Practice That .NET 8 Makes Possible

Sdílet
Vložit
  • čas přidán 19. 02. 2023
  • Use code REST15 for 15% off the new From Zero to Hero - REST APIs in .NET course: bit.ly/restchapsas
    Become a Patreon and get source code access: / nickchapsas
    Hello everybody I'm Nick and in this video I will show you a technique that you can use that leads to cleaner and safer code and I am also going to show you how .NET 8, optimized its biggest drawback.
    Workshops: bit.ly/nickworkshops
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: bit.ly/ChapsasGitHub
    Follow me on Twitter: bit.ly/ChapsasTwitter
    Connect on LinkedIn: bit.ly/ChapsasLinkedIn
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

Komentáře • 233

  • @nickchapsas
    @nickchapsas  Před rokem +24

    Yes you *could* return Array.Empty for some of those types, but returning an Array for a List or a Collection for the sole reason that the framework doesn't have any native types to support what you really want to return, is bad design. If it wasn't the Microsoft would be perfectly happy with us (and them) doing it and not add the types and migrate their own code to use them. We are getting it because it was missing. And btw this isn't a new thing or something revolutionary I came up with. Uncle Bob, Martin Fowler and Eric Lippert have all explained this already in their material (probably with better examples than mine which I will improve next time).
    Also when I talk about "validation" I am not talking about faults or errors but rather logical checks that you know will return nothing, for example someone passing a negative valid for pageSize or pageNumber. This will return nothing but I prefer to represent nothing as an empty collection rather than a null.

    • @javier-capello
      @javier-capello Před rokem

      This is a really cool guide! However, the service layer should never return an empty list or null when encountering a validation error (aka. business error). It's not the best practice.
      Returning an empty list or null may not be ideal in this case because it provides no information about the reason behind the empty result. This can lead to confusion, making it difficult for the client to differentiate between a validation error and a genuinely empty list.
      In case of a business error, the service should always throw a custom exception which the caller should gracefully handle. For example, the service can throw a `new ListUsersAccessDeniedException("You don't have access to list users.");` And the caller, for example, a Web API Controller, could handle this exception gracefully and return a nice error response to the client:
      ```
      403 - Forbidden
      { "code": "ListUsersForbidden", "message": "You don't have the necessary permissions to list the users" }
      ```
      Tune in for more good practices!

    • @S-we2gp
      @S-we2gp Před 5 měsíci

      Do we have any idea if this actually matters or what is gained practically?

    • @S-we2gp
      @S-we2gp Před 5 měsíci

      sorry I asked before i got to the second part of the video, appears you're doing some benchmarks now lol

  • @victor1882
    @victor1882 Před rokem +224

    The video about which collection interfaces to use and when would be awesome!

  • @Azcane
    @Azcane Před rokem +68

    An array *does* implement the types IReadOnlyCollection, IReadOnlyList, ICollection and IReadOnlyCollection.
    So for those return Types I always use Array.Empty() and it's a non-issue.
    The only type where this hasn't been possible is dictionaries. In those cases I usually just use an singleton if the type arguments are known at compile time.
    It's nice to have the same kind of cached empty object there too soon.

    • @nickchapsas
      @nickchapsas  Před rokem +5

      Using array.empty can raise questions from developers who read the code. "Why return an array for a list?" For example. It was possible but it would be very odd, which is why people made their own cached singletons of those types instead.

    • @nooftube2541
      @nooftube2541 Před rokem +8

      @@nickchapsas Is the same question as why return List as ReadOnlyCollection?

    • @Sayuri998
      @Sayuri998 Před rokem +11

      @@nickchapsas I don't get why returning an array from a method that returns IReadOnlyList would be confusing or bad design. To me, IReadOnlyList basically means a read-only iterable collection with random access. Basically an array. A list only adds the ability to add and remove elements in the array. So a read-only list == Array to me. What am I missing?
      Since interfaces on return types make it possible to return several different types that match the interface, why shouldn't we use that ability? It's one of the two cases I would use an interface in a return type for.
      Btw, I would prefer returning null because there is a difference between the case when there are no users and there is some error preventing us from getting users. I get that this is maybe not practical for existing code bases with nullability analysis disabled. But for new projects, I would definitely do it and require nullability analysis. I would treat all "maybe null" diagnostics are errors and require null checks.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      ​@@Sayuri998 It's bad design ONLY if the empty collection is the ONLY branch in which you return an array. Because at that point you are only doing it because the framework limits you by not providing an equivalent of Array.Empty for your normal. I've personally never seen a method that returns IReadOnlyList and in its contents it returns array in one branch, list in another and collection in another. It is always one because each method is doing one thing. That's why it's bad design.

    • @cyril113
      @cyril113 Před rokem +10

      @@nickchapsasyou can return an array in every branch. In fact I mostly use IReadonlyCollection in signature and Array as implementation. Most collections are results from the DB or linq expression. That being said I think the .NET 8 way is nicer.
      But I don't understand your argument. I'm pretty sure the .Empty property returns a different implementation than a "normal" collection. So you would be also returning a different implementation in one branch. Or is the argument that an array is not a collection? In C# it is.

  • @cliberto
    @cliberto Před rokem +23

    I disagree with what you said at 3:25, Arrays actually implement IReadOnlyList, so you CAN actually use Array.Empty.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Using array.empty can raise questions from developers who read the code. "Why return an array for a list?" For example. It was possible but it would be very odd, which is why people made their own cached singletons of those types instead. I know technically it is possible but not everyone has the whole implementation grab in their brain. Better remove any questions from the mix.

    • @powermetal1963
      @powermetal1963 Před rokem +3

      @@nickchapsas Isn't the same problem then with `ReadOnlyCollection` - why *collection* it is returning *list*? Also should we do a specific singleton for every possible interface? Btw, `Enumerable.Empty` is just a shortcut to `Array.Empty`. Most probably the same for `ReadOnlyCollection` you are so excited. The only really new is the dictionary one.

    • @nickchapsas
      @nickchapsas  Před rokem +3

      @@powermetal1963 It sure is but I find returning Array.Empty more appropriate for collections rathern than Lists. Also about enumerable.empty that's Incorrect. Enumerable.Empty is actually a cached instance of a new EmptyPartition. A has both a ToArray and a ToList method and if you see the implementation, ToArray will return Array.Empty and ToList will return new List.

    • @phizc
      @phizc Před rokem

      @@nickchapsas they can't start returning the new empty list for .ToList() when the IEnumerable is empty though.. I bet people are adding stuff to them now, so that would break things.

  • @rogeriobarretto
    @rogeriobarretto Před rokem +7

    That's a very interesting point you brought up there, regarding communication the intents from your methods. For example if I don't know my caller, should I assume that would be useful for it to get a list instead of a collection or an enumerable?
    I think those things are very interesting topics to be discussed
    Some discussions says we should apply 2 rules for it:
    - Accept the most basic type that will work
    - Return the richest type your user will need

  • @davidjsutherland
    @davidjsutherland Před rokem +1

    I'm keen on the collection type video you mention at about 6:15 in your video. Great work, as always Nick.

  • @vm123
    @vm123 Před rokem +14

    There should be empty keyword for that just like "default" keyword. It could be used in default argument values in methods.

    • @vm123
      @vm123 Před rokem +3

      ​@@milanstevic8424 no no no, I meant, they could introduce new keyword to the C# - "empty", so U could use it like this:
      public void DoSomeStuff(int[] ids = empty) { ... }
      or
      patter matching " if (ids is not empty)
      or if (ids != null && ids != empty)
      or int[] ids = empty;
      I also wish the added new operator "===" (triple equals) for comparing strings ignoring case and treating null as string.Empty.

    • @qnikbud
      @qnikbud Před rokem +1

      How about default working differently in those two cases (nullable and non-nullable lists):
      IReadOnlyList? a = default; //default means null
      IReadOnlyList a = default; // default means IReadOnlyList.Empty() because null would be illegal

  • @KoScosss
    @KoScosss Před rokem

    I heckin love subtle differences in syntax - from Array/Enumerable.Empty to ReadOnlyCollection.Empty (generic type placement)

  • @jongeduard
    @jongeduard Před rokem +10

    If I return null, it's definitely NOT to save memory. But for me, returning null means something DIFFERENT from returning an empty collection. For me, making things nullable or all has to do with intent. I *always* consider how the caller consumes the returned object. So in my programs, null values are treated in a special way, different from empty objects.
    Nevertheless, null is error prone and I will not deny that. Learning the Rust programming language made me aware of a much better approach:
    The Option and Result return types, using a language concept called tagged unions (Rust calls them enums).
    Basically, they mean that a value of a diferent variant is returned based on success or failure. The Option type can be Some, while containing the actual object as a payload, or None, which contains no value and basically represents the null state.
    Why? This system forces the code at compile time to always handle both situations, so that Rust does not suffer from this error prone problem of that C# still has.

    • @AA-yl9ht
      @AA-yl9ht Před rokem +2

      This was my first thought. I don't return a null because I don't have a result, I return a null because a result was not able to be generated. Returning an empty collection when there's a problem is just hiding the fact that there's a problem, since an empty user collection as a result of a validation failure, is indistinguishable from an empty collection returned when there's simply no users for a valid reason.
      I feel like the topic here is valid, its just framed really weirdly. If you have validation issues or errors you should be returning an object representative of those validation failures, or throwing errors. Not swallowing those issues and returning an empty collection.

    • @jongeduard
      @jongeduard Před rokem +1

      @@AA-yl9ht The topic is definitely valid, because the main focus was about the case where we actually decide to return empty collections, that we are getting new memory efficient solutions in the next DotNet version.
      My focus is specific about the question whether or not to return a null, and also about how I see an actual design problem in languages like C# that a newer language like Rust have solved.

    • @nickchapsas
      @nickchapsas  Před rokem +3

      @jongeduard In an idealy world, we would have real NRTs from the beginning of C# or union types and we wouldn't have to talk about this topic all together. The truth is that there isn't just a single .NET version or a single C# version, so addressing those topics if very important even for people who can't migrate. I'd prefer to not have null in the language all together. That being said, in a collection type, i'd very rarely use an option type because I don't believe in "None" in thie scenario. None is empty list.

    • @nickchapsas
      @nickchapsas  Před rokem

      @user-kk8ee7be2u I agree that I should have been a bit clearer with my result. This isn't about your traditional fault or error but rather just returning empty when something won't return a result with items. For example a used requests page -1 or pageSize -1. These parameters won't return any items in the list and it's unlikely for things like APIs to throw a 400. They'd probably return Ok, empty result and point you to the first page of items in the response. That's the sort of "validation" i was talking about but I should have communicated it better.

    • @Velociapcior
      @Velociapcior Před rokem +1

      @@nickchapsas no worries Nick. Returning null is bad practice and people just like nullchecks everywhere

  • @yuGesreveR
    @yuGesreveR Před rokem +2

    OMG!!! Finally! Now I can get rid of custom realizations of empty collections in the most of my projects. Great!

  • @behrad871
    @behrad871 Před rokem +2

    Hi nick thanks for the great topics you shared. It would be great if you make a video about explaining when to use different types like you mentioned in this video. Thanks again

  • @khwezimngoma
    @khwezimngoma Před rokem +1

    Thanks @Nick Chapsas, am bad with this thing of returning nulls, you have moved me enough that I will be refactoring my code to use what is there in dotnet 7. Not just for lists. If I mix this up with the Options Validation technique you showed in the other video, should get rid of a lot of null checks and guard clauses from my code.

  • @michaldivismusic
    @michaldivismusic Před rokem +2

    I personally prefer to return a failed Result object in case of a failure, but in cases where result isn't an option, I'd say both empty collection and null are fine. Though I'd only return null if the return type is explicitly marked as nullable.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      This will be less of a problem when (if) we get unions in the language

    • @michaldivismusic
      @michaldivismusic Před rokem

      @@nickchapsas that's right. In the meantime, libraries like OneOf and ErrorOr are very usable alternatives.

  • @sonics5439
    @sonics5439 Před rokem +2

    Hi Nick, Please make a video about which list type should be used and when. Thanks!

  • @dzllz
    @dzllz Před rokem

    Would love a video on when to use which collection or list type! Great work

  • @ziaulhasanhamim3931
    @ziaulhasanhamim3931 Před rokem +3

    With readonly list and readonly collection interfaces you could use Array.Empty in .NET 7, 6 etc.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Using array.empty can raise questions from developers who read the code. "Why return an array for a list?" For example. It was possible but it would be very odd, which is why people made their own cached singletons of those types instead.

  • @nooftube2541
    @nooftube2541 Před rokem

    Array.Empty() is also IReadOnlyCollection, IReadOnlyList, e.t.c. so it fit anything already.

  • @zbaktube
    @zbaktube Před 7 dny

    I really do not like the IReadOnlyList concept. We already have read only list called: array. I see what it tries to solve (or I think I see it 🙂), but I feel it as just a wrong concept to return elements like that. I could imagine instead a LazyArray concept or using Span (rec struct) or come up something similar by c#. What is your opinion?

  • @Dustyy01
    @Dustyy01 Před rokem +5

    On .NET 7 you can just make a static field which holds your empty list.
    Not as elegant and generic as the .NET 8 impl but better than null imo

    • @Rob_III
      @Rob_III Před rokem

      You could do that in .Net 1 😉

    • @Dustyy01
      @Dustyy01 Před rokem

      @@Rob_III Yea .NET 7 and downwards if u prefer that :)

  • @der.Schtefan
    @der.Schtefan Před rokem

    I would have hoped it would be found in List.Empty(), with an IReadOnlyCollection returned, especially because the types are getting more and more clunkier to write. Btw, even though it is great we have this now, be aware that you might not notice this in your typical web app. Any I/O with the outside world will be measured in milliseconds, the optimization in the nanosecond range is a million times below this. In this case it is even shorter than the typical RAS/CAS delay of the DRAM. Memory allocations for any database I/O request will be probably also far above 32 bytes. Yes, it all adds up, that is correct.

  • @georgemanius9499
    @georgemanius9499 Před rokem +1

    Great video, Nick, thanks. Have you considered making a series where you develop a full aspnet core API?

    • @nickchapsas
      @nickchapsas  Před rokem

      That's how the channel started. It's still up

  • @klaesregis7487
    @klaesregis7487 Před rokem +2

    In some cases I want to return null, in game development code should sometimes fail if the data is not correct. Rather that I get a hard bug and fix it than that I get weird behaviour because data is missing (which is a lot harder to debug generally).

  • @F1nalspace
    @F1nalspace Před rokem

    Finally! It just tooked 6 years for that feature for MS to implement... So i can now replace Array.Empty to ReadOnlyCollection.Empty. As a matter of fact, Array.Empty works in all 3 types, but it wont for dictionaries of course. But still, i dont see much difference of a IReadOnlyCollection vs IReadOnlyList vs IEnumerable. The only thing i see, is Count, but thats it. Linq is supported in all 3 in the same way, so what is the difference?

  • @KonradGM
    @KonradGM Před rokem +6

    I am curiouis Nick, you make courses regarding certain topics, which is great! but i would love to see a separate topic, in which you would showcase us how YOU learn about certain new subjects. Would be really helpful to some folks :)

    • @nickchapsas
      @nickchapsas  Před rokem +14

      I sometimes talk about it in the livestreams but I am happy to make a video on my research workflow

  • @th3oth3rjak3_
    @th3oth3rjak3_ Před 6 měsíci

    I'm with you, don't return null when the type signature indicates a real object.

  • @ExpensivePizza
    @ExpensivePizza Před rokem

    - Returning an empty list is not a good idea because the caller can't tell the difference between an error and a query that legitimately returned no results.
    - Returning null is also bad idea because there's not enough context about what went wrong.
    The correct behaviour is to throw and handle exceptions correctly. This is better for logging and informing the user that something went wrong because you can correctly log or display the actual cause of the problem. You can also implement a proper retry strategy and differentiate fatal errors from recoverable errors.

  • @DummyFace123
    @DummyFace123 Před rokem

    Interesting idea. I’ve always written functions as a service to other code.
    where I takes input however you want to provide it, and deliver output in the most practically way the over code could use it as.
    So usually I take in ienumerables but output lists.
    It sort of just being accommodating to other code. meal ready to eat, like sushi

  • @klocugh12
    @klocugh12 Před rokem

    Null and empty are not semantically equivalent.
    Empty means a collection exists, but has zero elements - for instance it was filtered and no records matched.
    Null means NO collection exists. It's up to design to specify whether existence of collection is expected or not. In most cases it is, but sometimes it might not be.

  • @timschwallie1589
    @timschwallie1589 Před rokem +1

    .Net Code Standard when returning a 'List', return a 'List', not null. Been like this since version .Net 1.0 Beta. There was one call in .Net Framework that broke this rule. It was fixed in I believe .Net 1.1.
    In this example, it was a validation that broke. That falls into a different SOC on how to manage validation breaches.
    The inclusion of using empty 'List's, nice. Time to remove a few static variables.

  • @andreisalagean1241
    @andreisalagean1241 Před rokem +5

    It would be great to have a video about why and which return types to use and their interface. Far as I understand you want to have as return type the lowest possible type that supports your result, but it kinda beats me why the return types are IEnumerable, and then some people do return result.ToList(), and not simply returning List or at least IList.
    Thanks for all the educational content ^^

    • @orterves
      @orterves Před rokem +1

      I think you're correct, accept and return the most abstract type that works for the internals of your method.
      People writing IEnumerable for their method but doing a ToList() on return are, generally speaking, writing bad code.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Great suggestion I’ll add it in the list

    • @Gippopotamtv
      @Gippopotamtv Před rokem

      There are great articles on this but I can't attach links to them :(

    • @billy65bob
      @billy65bob Před rokem +1

      I tend to prefer using IReadOnlyCollection as the most base type rather than IEnumerable.
      The reason for that is simply that I want to signal that the collection won't do anything funny if you enumerate it multiple times or enumerate it in strange ways.

  • @neociber24
    @neociber24 Před rokem +1

    I would like a video about the collections interfaces.
    This feature solve a lot of problems, but I still feel weird that using the regular List, people can just cast the IReadOnlyList back to mutate it.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Only if the unterlying type i a List. if the type is a ReadOnlyList containing the list then you can't

    • @Kitulous
      @Kitulous Před rokem

      and with a list, I believe you can call .AsReadonly()

  • @daStitches
    @daStitches Před rokem

    I have always been a fan of returning null, but I could certainly see myself starting to use these new Empty values.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      In an ideal world we'd all be using NRTs and we wouldn't have to worry about small things like this

  • @philofmilan
    @philofmilan Před rokem

    A video about ConfigureAwait would be awesome!

  • @cew182
    @cew182 Před rokem

    The List() constructor uses a static array size 0. Is it less efficient than these new methods?

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Yes. Size 0 means empty list but you still allocate the list object itself.

  • @himalmagar2895
    @himalmagar2895 Před rokem

    Great video 👌

  • @SparkyHou
    @SparkyHou Před rokem

    I assume if you are returning null or an empty list something wen wrong. What about your previous advice of returning a result and checking the status?

  • @quachhengtony7651
    @quachhengtony7651 Před rokem +1

    Question: does .NET have an equivalent of dev dependencies like in Node.js? For instance, concurrently npm package?

  • @_emnljrz
    @_emnljrz Před rokem +1

    Can you do a tutorial for http3/QUIC for c#? That would be helpful for a lot of us. Thank you.

  • @KingRecycle69
    @KingRecycle69 Před rokem +1

    Is it better to have the return type of a method be the interface of the collection or the specific type? Kind of off topic but was curious.

    • @oM1naE
      @oM1naE Před rokem

      ... it depends :D
      If you want to stay flexible in what you return, it's better to declare IReadOnyCollection or similar as return type. Then your callers really should not assume much, allowing you to change from returning List to Set for example.
      OTOH it can make usage of your method more cumbersome and less efficient. Nick in this video also speaks about returning IReadOnlyList from that method because "you are not supposed to add to this list". I am not really sure I agree here: As long as the repository returns an independent instance, why should it care whether the caller adds another element to the list, removes one, etc? Calling code which wants to do that then needs to call ToList on it (or maybe returnedList as List ?? returnedList.ToList() or something ugly like that), creating another copy of an instance just because the method does not promise to return a List.

  • @TheRicherthanyouguy
    @TheRicherthanyouguy Před rokem

    I know I shouldn’t be so one sided when it comes to programming but I agree with Nick and any one else who returns an empty collection when they can. I appreciate wanting to be concerned about the memory allocation but an unhandled null reference exception is way worse than poor memory allocation. I can’t wait for this feature tho

  • @Philippe42460
    @Philippe42460 Před rokem

    Thank you Nick for sharing this improvement for .net 8 this is a really nice feature especially for empty dictionary.
    I also saw your pinned comment about "Array.Empty" and I don't really understand what is the matter since an array is actually an IList, an IReadOnlyList and thus also an IReadOnlyCollection. So if I have a method returning an IReadOnlyCollection, I actually can return "Array.Empty", so why bother returning a wrapper of it, even though this is any invariant wrapper? Since the real returned type is not the method's user concern...
    Also, it would have been nicer if you presented the Array.Empty performance through your benchmarks.
    Anyway, thank you again for all your videos!

    • @nickchapsas
      @nickchapsas  Před rokem

      Because as the writer and owner of the method I wanna be very specific about what is being returned here. Not about the consumer but for me and the next person that will need to edit it. For example does it make sense to write a method that returns a list for every single one of its branches except for one which is the empty array? Sure it works, but conceptually it doesn’t fit. You only use it because it is a framework limitation. The moment the new empty collections are added you will move away because it fits more what you are trying to do. At least that’s how I see it.

    • @oM1naE
      @oM1naE Před rokem

      @@nickchapsas imho fits perfectly well. if the interface says you get an IReadOnlyList or IReadOnlyCollection nobody should care. if they really do, maybe the method should not return IReadOnlyList to begin with

  • @TonoNamnum
    @TonoNamnum Před rokem +1

    I totally agree with the idea of not returning nulls. If you plan on returning nulls then mark the return type as IList? Nullable. I guess the question is how often will there be exceptions. If there is an exception I will just throw it and have it buble up. I think the code is more readable and elegant like that. I know it's not that efficient but how often will you be throwing these exceptions.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      You should throw exception no quesiton about it. But when something logically makes sense to be "nothing" then i'd rather return an empty list than null.

    • @davidghydeable
      @davidghydeable Před rokem

      @@nickchapsas In another video about the Result type you said you don't like throwing exceptions. Would you be able to clarify this?

  • @frost.6647
    @frost.6647 Před rokem +2

    immutable collections in System.Collections.Immutable should be better for this scenario. It has a Empty static cache, and they does not implement the mutable IList, IDictionary interfaces, which prevents you from doing something wrong.

    • @nickchapsas
      @nickchapsas  Před rokem

      It doesn’t but it is slower because it’s using a tree behind the scenes

    • @frost.6647
      @frost.6647 Před rokem +1

      @@nickchapsas Does it matter for an empty collection?

    • @nickchapsas
      @nickchapsas  Před rokem

      When an empty collection is the least common scenario; then yes

    • @ewdlop1
      @ewdlop1 Před rokem

      what about the frozen collections in .Net 8

  • @tunawithmayo
    @tunawithmayo Před rokem

    Nullable types generates really good compiler hints and warnings now, so that consumers of them know to check for null. Meaning, returning null is a lot less dangerous now.

    • @nickchapsas
      @nickchapsas  Před rokem

      Oh yeah absolutely. If you can enable NRTs and mark nullable warnings as errors then this is way less of a problem. Still handy when you actually wanna return an empty collection though

  • @jameshancock
    @jameshancock Před rokem +1

    We really need native unions so that instead of throwing errors, we return the error and then you don't return an empty anything, you return an error and then handle the error returned instead of the valid result type.

  • @RobinHood70
    @RobinHood70 Před rokem +1

    For dictionaries, there's already ImmutableDictionary.Empty. There's also a static Create() method on the class that returns the exact same thing, but unless I'm missing something, I think about the only benefit it gives you is working around analysis warnings to not use static properties of generic classes.

    • @nickchapsas
      @nickchapsas  Před rokem

      The ImmutabeDictionary is a completely different data structure, that you wouldn’t return in the place of a readonly dictionary. If has very different functionality.

    • @RobinHood70
      @RobinHood70 Před rokem

      @@nickchapsas I agree it's not ideal, much like returning an Array.Empty in place of a list, but it *does* satisfy the requirement of an IReadOnlyDictionary with a static Empty value. It was even suggested as an option in dotnet runtime's GitHub, Issue #24031, which was where I first found out about it.

  • @kaisersolo76
    @kaisersolo76 Před rokem +1

    I would like a video on the list types and when to use.

  • @stefanotorelli3688
    @stefanotorelli3688 Před rokem

    But is there any way to do the same with mutable collections? Just suppose you need to return a empty mutable collection, is there any way to avoid allocations?

    • @nickchapsas
      @nickchapsas  Před rokem +1

      You can't because if it's mutable then you'll have a reference to that immutable collection that you can mutate and then it's no longer empty

  • @timramone
    @timramone Před 4 měsíci

    Is ReadOnlyDictionary an instance of an IDictionary? What'll happen when I mutate it?

  • @tomwimmenhove4652
    @tomwimmenhove4652 Před rokem

    I have mixed feelings. Sometimes returning a null can have a different meaning than an ampty list. Imagine you're asking for "Students" in whatever data source; retuning an empty list can mean that there are zero students, while null could mean there is nu such thing as "Students" in whatever data source.

  • @parlor3115
    @parlor3115 Před rokem

    Shouldn't we throw or return a nok result if validation fails or the database call fails? Return an empty list is not right in this case.

    • @nickchapsas
      @nickchapsas  Před rokem

      Depends on the validation. When the user passes pageNumber -1 for example I would return empty collection early because I know there is nothing that will match that value

  • @harveycovey2215
    @harveycovey2215 Před rokem

    Would it make sense then, if you're still on .Net 7, to instantiate constant empty objects that you call each time instead of returning NULL? That way, you are still only returning the same allocated empty object. For example, if I know I'm always returning empty List, I could create a variable EmptyList that is of List and always return that variable instead of instantiating a new one or returning NULL.

    • @Pasi4K5
      @Pasi4K5 Před rokem

      This is very dangerous though. Since you can just freely add and remove elements from a List, anyone with access to this List object (including the consumer of the method that returns it) can change its content.

    • @oM1naE
      @oM1naE Před rokem

      only if you are declaring them as IReadOnly..., as the other response already says.
      imho it makes more sense to return the existing immutable empty objects, like
      - Array.Empty() for all IReadOnlyList / IReadOnlyCollection
      - ImmutableSet.Empty for IReadOnlySet
      - ImmutableDictionary.Empty for IReadOnlyDictionary

  • @sebdoucet_fr
    @sebdoucet_fr Před rokem

    FYI Array.Empty can be used and cast as IReadOnlyList

  • @guiorgy
    @guiorgy Před rokem

    First of all, what would happen if the caller modifies the collection, if it's a singleton, will all subsequent "empty" collections be modified?
    Secondly, couldn't you declare a private static readonly collection in your class and always return that instead of a new empty collection?
    And lastly, is there any benefit to using one of the above over the other (except for not having to write code to declare the empty collection manually)

    • @nickchapsas
      @nickchapsas  Před rokem

      The caller will get an exception because you can’t modify a readonly construct. Yes you could make an empty singleton and return that instead. That’s what I’ve been doing till now

  • @MagicNumberArg
    @MagicNumberArg Před rokem +2

    Returning an empty collection when an operation failed is a very dangerous thing to do, a straight path to having a whole department worth of people missing from an otherwise innocuous looking report. Its better to throw, if failure is expected to be rare or return some form of Result, if it's expected to be frequent. Speaking of which, is there any Result library you could recommend?

    • @nickchapsas
      @nickchapsas  Před rokem +1

      It’s definitely not dangerous. There are many scenarios where invalid doesn’t mean error and allocating an option type reason for every option is excessive. I like LanguageExt for results and options btw

    • @MagicNumberArg
      @MagicNumberArg Před rokem +2

      @@nickchapsas we are not doing Rust 😉. When writing C#, business logic bugs are typically a much bigger priority than a few unnecessary allocations.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      @@MagicNumberArg Disagreed for two reasons. First Rust actually has both a native result and an option type. Second, performance is contextual, and the graphs you see microsoft post about how fast C# is, wouldn't it be possible without changes like these.

  • @PaulMartins-pv6rg
    @PaulMartins-pv6rg Před rokem +1

    Any benefit to returning IReadonlyList over IEnumerable? Is it solely to indicate that there is no risk of deferral on the IReadonlyList?

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Being specific with the type communicates the intent to the consuming method

    • @Dustyy01
      @Dustyy01 Před rokem +2

      IReadOnlyList grants access to the index aswell.

    • @Soraphis91
      @Soraphis91 Před rokem +3

      also, isn't iterating over it via foreach allocate heap memory for IEnumerable, but list has an struct enumerator implementation!?
      (okay, seems like 'IList' has the same issue of heap memory allocation, while 'List' does not. Also foreach on IEnumerable does not allocate heap memory for Enumerable.Empty, but returning a List as an IEnumerable does allocate memory (tested on .net 6))

  • @luvincste
    @luvincste Před rokem

    how would returning an usable value (empty collection) agree with making clear the intention of "it didn't work", apart from the fact that it could be a loaded value (it could really be an empty list)... i can accept not returning an exception, but this seems to me like being "too comfortable"

  • @Linkario86
    @Linkario86 Před rokem

    I kinda fail to see an actual use case for this. I usually want to add items into my Lists and since I have to use ReadOnly Type and return Type where I can't add anything to my List, how can I utilize this in my actual productive application?

  • @F2H16
    @F2H16 Před rokem

    Where do I get the dotnet 8 alpha?

  • @AndrewMorison_morrie
    @AndrewMorison_morrie Před rokem

    Would love a video on each list type..

  • @therealgamer8150
    @therealgamer8150 Před rokem

    Q: Wouldn't this introduce ambiguity between "The query failed" and "The query executed successfully and returned an empty result"? Surely if your query fails you wanna know about it. So it would make sense not to try to save the protect consumers but make sure it breaks loudly then and there? Aka in this scenario you should probably throw an exception and not have a return statement at all.
    I understand for API's you wouldn't want your API to throw exceptions, but within apps this doesn't seem like the right thing to do because its giving the developer a false sense of security. What's your take on that?

  • @antonmartyniuk
    @antonmartyniuk Před rokem

    I prefer to return an empty collection. This new thing will become handy even in entity models, so your nested collections are never null

  • @Fafix666
    @Fafix666 Před rokem

    I understand this is quite memory efficient, but why not return a Null Object or a Result Object to stop early? Pretty such that's the most efficient and performant solution in most cases.

  • @superpcstation
    @superpcstation Před rokem +1

    I just always return Array.Empty. Is there something wrong with this approach?

    • @superpcstation
      @superpcstation Před rokem

      for dictionaries, i do see this is beneficial. Previously i'd create a static readonly dictionary of size 0 and return that instead.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Using array.empty can raise questions from developers who read the code. "Why return an array for a list?" For example. It was possible but it would be very odd, which is why people made their own cached singletons of those types instead, which I actually prefer over the Array.empty

    • @superpcstation
      @superpcstation Před rokem

      @@nickchapsas ah that helps. Thanks Nick

  • @ryanelfman3520
    @ryanelfman3520 Před rokem

    What was that website you advertised that had all those boilerplate projects?

    • @nickchapsas
      @nickchapsas  Před rokem

      abp.io ?

    • @ryanelfman3520
      @ryanelfman3520 Před rokem

      @@nickchapsas hmm maybe. I thought it was one that had different boilerplate samples

    • @ryanelfman3520
      @ryanelfman3520 Před rokem

      @@nickchapsas Wait I think this might be it

  • @ilh86
    @ilh86 Před rokem

    Is there a version for sets?

  • @user-di8kl4cc5u
    @user-di8kl4cc5u Před rokem

    Howdy Nick!

  • @Any1SL
    @Any1SL Před rokem

    The problem is the method contract is to return a user collection which is misleading to consumers when there are errors which is why I use the Maybe/Result pattern

    • @nickchapsas
      @nickchapsas  Před rokem

      You shouldn't return empty collection when there is an error. But when you know the result will be "nothing" and you want to shortcircuit the method before it goes any further just return empty instead of null.

    • @Any1SL
      @Any1SL Před rokem

      The Result pattern is a class that returns a T data, bool IsSuccessful, and Errors back to the consumer so instead of returning null or empty the consumer can check if request.IsSuccessfull. I saw this on a Pluralsight tutorial which I borrowed it.

  • @NuKleArNyPL
    @NuKleArNyPL Před rokem

    I want to see a video with every type of collection

  • @jameshancock
    @jameshancock Před rokem

    PS: Why not use IReadOnlyArray? It should be faster than IReadonlyList anyhow and you can return Array.Empty from it?

    • @nickchapsas
      @nickchapsas  Před rokem

      You can return array.empty with ireadonlylist too. The point is that the types have to mean something for your application. A list is different from an array etc

  • @iGexogen
    @iGexogen Před rokem

    I return null instead of empty collection in cases where null used to report back unexpected failure and to distinguish it from successful but empty collection. I find that this design pattern smells, but it sometimes occur in my code.

    • @Rob_III
      @Rob_III Před rokem

      I don't understand that; it means after every call you have to check for a null result. Just throw an exeption. In Nick's example for example: If validation fails, throw a validation exception, if the database connection fails, throw a database exception. If everything went alright, just return the customers/users/whatever. That MAY be an empty list when there are no customers/users/whatever. But the result is either an empty list, a list with items (both which are enumerable) OR an exception - which can be handled at the appropriate level(s) upwards. So you can catch "NotFoundExceptions" or "ValidationExceptions" in a (semi-)global exception handler and return the according HTTP exception for example (404 or whatever).
      If you return null your code is littered with "If (customers == null) ..." everywhere. And then you still have no clue WHAT went wrong, just THAT it went wrong.

    • @iGexogen
      @iGexogen Před rokem

      ​@@Rob_III Every null needs to be checked and every exception needs to be caught, even if your try/catch is hidden in exception middleware it's still there. For your simple web example you can say that you reduced boilerplate that's for sure, but this is only top presentation layer where you have that last line of defense like global exception handlers. And what about other layers where you call method and expect it to throw exception? Right, you need to litter your code with with try/catch which bloats code much more than null checks and also not free in terms of performance. In most cases where failure reason makes sense I prefer returning OneOf result objects instead of throwing exceptions, but in some rare cases when failure reason doesn't matter I can use such "safe" methods from first comment, caller can be sure that method "eats" all unxpected exceptions, all it needs is to call method and make decision based on result, there is no reason to make signature of such methods more complicated or wrapping their calls in redundant try/catch.

    • @Rob_III
      @Rob_III Před rokem

      @@iGexogen "Every null needs to be checked" > Not if your methods can't even return null.
      "and every exception needs to be caught" > No, because you can let them bubble up
      "Right, you need to litter your code with with try/catch" > No you don't. I generally have 2, maybe 3 try/catches in my projects. One of them is a global fatal exception handler, one an exception handler for the UI/User cases and that's about it. You just need to throw application-specific exceptions. Derive them from "MyAppException" (which you derive from Exception) and JUST catch MyAppExceptions. Then you can throw "CustomerNotFoundException" or "SomethingElseException" all you like, your "global" exception handler will handle those and return the correct HTTP response/ProblemDetails result. All other exceptions (FileNotFound, DivisionByZero etc. shouldn't happen in the first place; and those can be caught by the _actual_ global exception handler for logging etc.).
      "I prefer returning OneOf result objects" > I agree that's also a nice solution.

    • @iGexogen
      @iGexogen Před rokem

      @@Rob_III Having base exception for business logic layer makes sense, I also have it (AbstractApplicationException in my case). But it doesn't cancel my statement that every exception must be caught, there is only one outcome for unhandled exception - application crash. There is always some outer try/catch depending on execution context that gives you ability to specify custom delegate for that task (exception handler middleware for web). Same about my statement that every null have to be checked. Not dealing with nulls at all sounds very dogmatic and never achievable like efficient pure functional programming. For business layer it makes perfect sense to avoid nulls in favor of "null-objects" or something like that, it is layer that frequently chages and sometimes concurrently by many developers, being elegant and error proof is in first place for this layer. But you still have to deal with standard library, 3rd party packages or even own code from lower layers where maintaining null-free code can be real overengineering, so you will have to deal with null checks a bit even if you don't want to. In general I clearly understand what you stand for, and also using all that techniques in suitable places.

    • @Rob_III
      @Rob_III Před rokem

      @@iGexogen I just don't see the point of "internally" catching a DBException and returning null from a GetCustomers and having to check for null values all over the place where GetCustomers is used instead of it simply bubbling up and being handled in one single place _and also_ getting rid of all null checks in the proces. Ofcourse there's always an outer try/catch (or there should be). Use exceptions what they are for: exceptional conditions. Don't sweep them under the rug because they're 'expensive'. They shouldn't happen in the first place (which also means exceptions shouldn't be used for 'normal' or 'happy path' program flow). But when you can't connect to the database you got a problem. Instead of saying "hey, GetCustomers returned null, anything could be wrong", let the exception bubble up and let the handler take care of logging, create ProblemDetails and/or whatever else it's supposed to do. Or are you taking care of logging the exception and whatever else needs to happen in the GetCustomers method as well?
      If you really want to, you can still wrap the GetCustomers in a try/catch at the callsite and do whatever you want with exceptions, but generally: let exceptions bubble up. Take care of exceptions you KNOW how to handle (at the suitable place) and for the rest: let them bubble up further. If that, eventually, means a 'crash' of the request: good! Better than an application that's in some unknown (potentially dangerous) state. It also means problems are spotted earlier and are taken care of (bugfixed) earlier. So: when opening a file you're not sure exists: by all means just try to open it and catch a "FileNotFound" exception at the callsite and create the file and continue - if that's what you want. But if the application is supposed to have some data file that isn't there: just open it, did it cause an exception, let it bubble up _unless_ you know how to handle it at the callsite. (We could go into an entire discussion about checking first if a file even exists, but that is pretty pointless; in a race condition it may be there at the time you check and the split-second later you try to open it the file _may_ be gone; so just try to open it without checking. But that's another discussion).
      I agree that 3rd parties can complicate things by still returning nulls but since we have nullable reference types (C#8, 2019) things have gotten a LOT easier for your own code. I don't agree that it can be "real overengineering", it usually makes thinks actually simpler, clearer and more concise.

  • @danielemanicardi7889
    @danielemanicardi7889 Před 6 měsíci

    Both returning null or an empty list are bad practices, since you're collapsing error scenarios to the same return value. The best thing to do is throwing exceptions, using .NET ones or defining them when dealing with your internal logic

  • @alexanderkvenvolden4067

    Even if you're not on .NET 8 yet, there's nothing stopping you from making a static empty instance of your own of any type that you can return whenever you need an empty anything.

    • @nickchapsas
      @nickchapsas  Před rokem +3

      Absolutely. That's what I've been doing for years. Now MS just ackowledged that this was missing and they now added it. That's it

  • @7th_CAV_Trooper
    @7th_CAV_Trooper Před rokem

    Which is better, Enumerable.Empty or Array.Empty?

  • @QwDragon
    @QwDragon Před rokem

    Nice feature, but bad example. If it is some kind of search, empty list is normal result like nonempty one.
    But if validation fails, you should not hide it under null or empty list - you should throw exception.

    • @nickchapsas
      @nickchapsas  Před rokem

      I didn't explain validation correctly in the example. It's more about logical validation failure like a negative value in pageSize or pageNumber. Not necessarily something that warrants an error or a fault. Basically filtering that you know will return not results so you don't even bother.

    • @QwDragon
      @QwDragon Před rokem

      @@nickchapsas I think negative page size is supposed to be an error. Othewice negative one can be expected to mean all without paging.

  • @Arcadenut1
    @Arcadenut1 Před rokem

    I prefer to return NULL so that I can distinguish between no results and some other issue.

  • @mattwise666
    @mattwise666 Před rokem

    Returning empty for me, but if I was to return null that return type is getting a ? Nullable enabled!!

  • @paviad
    @paviad Před rokem

    Why can't you return a static empty list in .net 7 instead of allocating a new one?

    • @fedefex1
      @fedefex1 Před rokem

      What if someone adds an element to that list for whatever reason?

    • @paviad
      @paviad Před rokem

      @@fedefex1 then create a static read only list and return that

  • @kaiserbergin
    @kaiserbergin Před rokem

    And now for a vid on frozen collections!

  • @keykey76
    @keykey76 Před rokem +1

    The issue with returning an empty anything instead of a null is that you disguise a validation error or db communication error as "there was no data to return", which is not the truth - you have hidden the exceptional situation from the consuming user and made them think there is just no data. And the error goes unnoticed.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Pretty sure I did t mention anything about db communication error in the video since that would be a 500 error. By validation I mean that what the user submitted wouldn’t match any items anyway, for example request pageNumber -1 or page size 0. Also, there is a different between an error and a fault.

    • @keykey76
      @keykey76 Před rokem

      @@nickchapsas Exactly, if due to the passed parameters like pageNo equal to -1 validation makes you return an empty collection, that is completely fine to me; but if you decide to return an empty collection in case of some error, then I would say the error should surface if not by exception then by returning null, to distinguish from the state of "no data to return"

  • @valentinnikolov2474
    @valentinnikolov2474 Před rokem

    Hello Nick, it would be awesome to create the video you suggested!

  • @brianviktor8212
    @brianviktor8212 Před rokem +2

    That's a nice change, but the main reason for returning 'null' is to return something that indicates a general failure of the process, like a failure to read the database, bad input or internal error. An empty collection indicates the query was successful and no match was found. If both cases return an empty collection, it can cause problems for the developers in finding the problem. But if you catch the error otherwise (event, logs, etc), then returning an empty collection is fine. Also note that the consumer should know what the query returns in case something fails.

  • @djp_video
    @djp_video Před rokem

    NULLs for error conditions, empty lists for empty resultsets.

    • @shanehebert396
      @shanehebert396 Před rokem

      or exceptions. If your call had an exception (can't access the database, can't access the website, etc.) then throw an exception as those are not expected behavior. IMO, don't hide the error condition. If you return NULL then the above code still has to deal with it in addition to having the extra code to check for NULL or it will generate yet-another-exception.

    • @nickchapsas
      @nickchapsas  Před rokem

      Nulls never when possible. Nulls very bad.

  • @ryan-heath
    @ryan-heath Před rokem +6

    The problem with returning an empty list, instead of null, is that you then just have swallowed an error.
    Or you need to communicate the error in another way, like options or retvals, which are checks too ...

    • @Azcane
      @Azcane Před rokem +5

      Imho, by definition, this shouldn't be an error. If the behavior "there are no elements to return" is an error state, one should throw an exception but not return a null. Returning a null would just hide the actual error and make it a NullRefEx instead.
      And if it's the job of the caller to decide if that's an error, there isn't much difference between checking for null or checking if the collection is empty.

    • @krzysztofzon8661
      @krzysztofzon8661 Před rokem

      My solution to such scenarios is to use a generic Result object to wrap the return collection. Thanks to this approach i can avoid returning a null and the access to occured errors is preserved.

    • @Plug1ndk
      @Plug1ndk Před rokem

      How is returning null different with regards to swallowing errors?

    • @orterves
      @orterves Před rokem

      Returning null doesn't improve the situation over an empty list in that case though, you've still swallowed the error and returned something that is actually more work to get around. If it's important to identify the error case explicitly then I would choose to throw an exception or return a Result before returning null

    • @agsystems8220
      @agsystems8220 Před rokem +1

      Returning a null chokes on an error instead. It is the worst of both worlds, because the caller still has to deal with the possibility, but unlike an option it doesn't tell the caller what the error actually is. Code should either spit errors back out, or swallow them. Returning a null is neither of these.
      You definitely need to be sure of yourself when writing code like this, but keeping validation failures outside of business logic is often a good idea. In particular, imagine a method that takes a list of transactions, validates the submitter, then validates each transaction, then returns the filtered list of valid transactions. The business logic doesn't care that the submitter was false (though the method may alert some other system), all it cares about is the transactions it has left to deal with. It might be able to shortcut some of it's code due to the empty list, but it should not care why the list is empty.

  • @ryanelfman3520
    @ryanelfman3520 Před rokem

    Ahh u should have benchmarked returning null against the collection empty

  • @x0rld159
    @x0rld159 Před rokem

    I always prefer to not return null

  • @Sayuri998
    @Sayuri998 Před rokem

    Also, why some of these read-only types implement mutable interfaces is beyond me. This is a clear violation of a couple of principles, among them Liskov Substitution Principle and Interface Segregation Principle.

  • @elraito
    @elraito Před rokem

    Im fairly newbish but why not jist throw an exception right away? Your frontend needs info that things are bad anyway. If you return empty lists all ypu are doing is saying its frontend problem now

    • @nickchapsas
      @nickchapsas  Před rokem

      The operation might not be an error or a fault. For example someone tries to get page -1 or pageSize -1. I wouldn't throw an exception there but rather just return an empty collection and probably have an appropriate message with the first and last page the user can retrieve. Exceptions are expensive and they should be thrown in exceptional situations

  • @haxi52
    @haxi52 Před rokem +3

    Its a good feature to add to C# 8, but performance is not a good reason for people to pick this over returning null. In either case null or empty leaves the door open for bugs. By far null is worse, but empty collection still doesn't tell you what went wrong, or even if something went wrong. I would much prefer throwing and/or logging. Especially for error contacting the DB. An empty list just doesn't tell me something is horribly wrong with my application, but and exception/log will. Performance is fun, but really need to stop teaching devs to focus on it until it becomes a problem. There are other languages better suited for focusing on performance.

  • @mariocamspam72
    @mariocamspam72 Před rokem +1

    comment

  • @keyboard_g
    @keyboard_g Před rokem +3

    These clickbait titles and covers make searching your content impossible.

    • @nickchapsas
      @nickchapsas  Před rokem

      It doesn't matter, because the content is topical, not evergreen. When .NET 8 is eventually out there will be an evergreen-named version of all the changes in a single video, like i do with C# versions as they come out.

  • @briannielsbergh
    @briannielsbergh Před rokem

    Are we trying to scare all new c# developers? Are this code going to run on an Arduino? Seriously as of 2023, we are really wasting out time with this nonsens.

  • @_samirdahal
    @_samirdahal Před rokem +1

    Seriously? Everytime I watch his new video title it's already .NET (N+1) 😲

  • @GoranHumlestol
    @GoranHumlestol Před rokem

    If your method returns IReadOnlyList you can already achieve this with Array.Empty, ImmutableArray.Empty or ImmutableList.Empty. Similarly with ImmutableDictionary.Empty. These new APIs are nice though.

    • @nickchapsas
      @nickchapsas  Před rokem +1

      I've already addressed this in the comments so give them a looksy

  • @peter.dolkens
    @peter.dolkens Před rokem

    I disagree with returning an empty list if the *result* isn't actually an empty list.
    var targetUsers = instance.GetRemoteUsers() ?? instance.GetBackupUsers() ?? Array.Empty();
    This line of code allows me the flexibility to choose how to deal with invalid responses and clearly differentiates between an *empty* result, and an *invalid* result.
    It also behaves the same way for reference types:
    var targetUser = instance.GetRemoteUser() ?? instance.GetBackupUser() ?? User.DefaultProfile;
    At the end of the day, null != Array.Empty

    • @nickchapsas
      @nickchapsas  Před rokem +1

      You could very easily do the same and have Any checks instead of null checks. Now you just run the risk for your code blowing up due to NREs. I don't like this approach unless you are using NRTs and you have nullable warnings turned on and marked as errors so people are forced to handle them.

    • @peter.dolkens
      @peter.dolkens Před rokem

      @@nickchapsas but any Any check is still different.
      I might actually have 0 participants on my course, or maybe the call to get the number of participants on the course failed, but that's a non critical error, unless I'm trying to calculate the remaining course capacity. This is where null lets me make that decision at design time.
      Without discriminated unions, null is the closest we have short of throwing exceptions.
      NRTs at least satisfy your requirement of showing intent.
      I'd also argue that the null approach encourages more resilient code, whilst the empty collection approach discourages resilience in other areas of your code, because the collection instance "just worked".
      If I always return null when a non-fatal error occurs, then I learn to always check for null, or use null conditional operators or null coalescing operators.
      I also think it's easier to see intent this way during code review. It's explicit what action to take if something is null, Vs empty, Vs populated. Empty collections when something goes wrong hide this away.

    • @peter.dolkens
      @peter.dolkens Před rokem

      All that said, I still found this video helpful, because I'll use these new Empty properties instead of new collections when setting up my explicit null coalescing fallbacks 🤣

  • @nertsch77
    @nertsch77 Před rokem

    An instance of an empty Readonly Dictionary is already available since .net Core 1.0 via System.Collections.Immutable.ImmutableDictionary.Empty

    • @nickchapsas
      @nickchapsas  Před rokem

      That’s an immutable dictionary. Immutable data structures are a completely different thing

    • @iGexogen
      @iGexogen Před rokem +1

      @@nickchapsas In terms of serving as empty static collection I don't see any difference. I am using them for same goal but in .NET 7 projects and don't see any reason not doing it.

    • @nertsch77
      @nertsch77 Před rokem

      @@nickchapsas Yes Immutable data structures are a different thing, but if you use it to supply an empty dictionary for a parameter of type IReadOnlyDictionary, that doesn't matter.