The New Way of Parsing ANY Type in .NET

Поделиться
HTML-код
  • Опубликовано: 17 май 2023
  • Check out my courses: dometrain.com
    Become a Patreon and get source code access: / nickchapsas
    Hello, everybody, I'm Nick, and in this video, I will show you a really cool feature that was added in .NET 7 that allows you to parse strings into any type with a consistent interface and programming model.
    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

Комментарии • 116

  • @michielvanhimbeeck6206
    @michielvanhimbeeck6206 Год назад +115

    I love how random your numbers are

    • @MarkCastle
      @MarkCastle Год назад +10

      Not watched it yet…. 69 by any chance? 😂

    • @dmytrk
      @dmytrk Год назад +3

      ​@@MarkCastleand then splits it with comma "6,9"😂

    • @kriscavitt3479
      @kriscavitt3479 Год назад +6

      And 4,20

    • @marsgal42
      @marsgal42 Год назад +1

      The only numbers that matter are 13 and 42. 😛

    • @jonathanbout
      @jonathanbout Год назад +2

      The like count of this comment is one of them

  • @carldaniel6510
    @carldaniel6510 Год назад +120

    All of the new "generic math" interfaces are awesome - long overdue. But please - DON'T implement TryParse as a call to Parse inside a try-catch. One of the key benefits of TryParse is that it does not throw - even internally. Implement Point2d.TryParse as two calls to int.TryParse and return true only if both succeed - no throw/catch inside.

    • @Sindrijo
      @Sindrijo Год назад +8

      Agree, only implement TryParse with other TryParse. I usually also implement the Parse with the TryParse version of the same type.

    • @nickpolyderopoulos3491
      @nickpolyderopoulos3491 Год назад +5

      I am pretty sure Nick did not do Try Parse as you propose for simplicity reasons. It is not a best practices video.

    • @amirhosseinahmadi3706
      @amirhosseinahmadi3706 Год назад +1

      "One of the key benefits of TryParse is that it does not throw - even internally"
      Could you explain what how that's a benefit? Genuine question. Wouldn't it be functionally the same?

    • @sszzt
      @sszzt Год назад +3

      ​@@amirhosseinahmadi3706 It is just for performance reasons. Returning false is as fast as you can get. Throwing an exception requires much more processing and memory allocations. Of course you have to weigh up whether it's worth optimising your method for your particular use case. But stick to what @Sindrijo has said and 99% of the time it will be the right decision.

    • @dennycrane2938
      @dennycrane2938 Год назад +1

      I was actually going to comment the same. I do it the other way around. I do the validations during the parse implementation and just short-circuit if anything is wrong and return false. Then Parse just calls that and throws if it fails.

  • @woocaschnowak
    @woocaschnowak Год назад +14

    When MS said they will add static interface members, I thought, they lost they mind. But now, that they provided such use cases, I'm changing my opinion :-)

  • @quranthecompanion4528
    @quranthecompanion4528 Год назад +5

    we used to use Convert.ChangeType() for primitive data types. now we are changing the implementation to IParsable. its pretty neat.

  • @SvdSinner
    @SvdSinner Год назад +2

    This was a great blend of useful right now, interesting and showing future functionality. Kudos!

  • @mariocamspam72
    @mariocamspam72 Год назад +8

    10:11 We're circling right back to pre-2000s C, haha

    • @davidtaylor3771
      @davidtaylor3771 Год назад +4

      No we are not, that's the point. We can do what you did in pre-2000s C, but in a modern secure type safe way with extremely readable code.

  • @zoran123456
    @zoran123456 Год назад +12

    Understood everything up to 2:00. After that my brain went coo-coo!

    • @davidtaylor3771
      @davidtaylor3771 Год назад +2

      That stuff at the end was interesting because it showed a relatively easy way to do parsing in .net 8 without allocating anything other than the initial input lines. Imagine you were parsing a large CSV file where you always had 10 fields per line separated by comma. You can split that string into 10 fields and do stuff with the fields (like converting them to types like DateTime, int, double, etc) all without any additional string allocations. Nothing extra for the garbage collector to deal with.
      And the code was relatively readable and very secure. It would perform like lightning if you were parsing huge files.

  • @dvldev
    @dvldev Год назад

    Great! I am watching your video since last month. I have completly changed the way of how I write code. Thank you very much Nick.

  • @cn-ml
    @cn-ml Год назад +3

    I really like the new Span splitting method, makes me feel in control of my memory. Also i totally love the new abstract interfaces, especially the IParsable, but I probably used INumber a lot more already.

  • @alexanderkvenvolden4067
    @alexanderkvenvolden4067 Год назад

    I love these new interfaces and the ability to have static interface methods, and use them IF the code base I'm working on is using the supported runtime.

  • @ntohl
    @ntohl Год назад +20

    Nice. In the ReadOnlySpan TryParse example. Shouldn't it return false instead of throwing ArgumentOutOfRangeException?

    • @nickchapsas
      @nickchapsas  Год назад +14

      Yes you are right. I copied and pasted it from the Parse method so I totally forgot. Thanks for bringing this up

  • @haveaniceday4585
    @haveaniceday4585 Год назад +2

    Hey Nick, I saw you yesterday at Techorama. Thanks for the great talk!

  • @drndn
    @drndn 11 месяцев назад

    I appreciate how you use a similar naming scheme to me, semantic-type-as-physical-type, eg FooAsText, FooAsInt etc.

  • @gneto.r
    @gneto.r Год назад

    Okay maybe I need to rewatch this later after a cup of coffee or two... looks like something useful to fully understand.

  • @diadetediotedio6918
    @diadetediotedio6918 Год назад +3

    I very much like this feature, I would rather prefer the "shapes" approach but this is really very very very userful

  • @AEF23C20
    @AEF23C20 Год назад

    two points used from some buffer [read i/o etc], and this buffer easy to imaging as array, and then change type of this array, and array type - desired type of structure array

  • @TheAaandyyy
    @TheAaandyyy Год назад

    Great video. One thing that I was missing was to introduce the [NotNullWhen(true)], but maybe that is the separate topic itself

  • @OXARA
    @OXARA Год назад

    Good practice for csv line parsing

  • @josephmoreno9733
    @josephmoreno9733 Год назад +1

    Static abstract methods port interfaces to types beyond the instance of those types. And that is really impressive. With that, the need for the use of reflection is reduced as much as possible.

  • @craigmunday3707
    @craigmunday3707 2 месяца назад

    Very useful, thanks.

  • @timseguine2
    @timseguine2 Год назад

    Not sure If I am going to use this technique, but I did learn about static abstract members now, which I didn't know about before.

  • @Yogs01180
    @Yogs01180 Год назад

    This can be cool ! Thanks ! ❤❤

  • @Naton
    @Naton Год назад

    i use 'is' syntax and return an Option

  • @T___Brown
    @T___Brown Год назад

    Question: is there something built in that can do fixed width? Currently i have to do a lot of specific span reads but if there was a range like you had that i could split based upon multiple indexes then that might be better

  • @GekoPoiss
    @GekoPoiss Год назад

    I'd recommend using a parser combinator library instead. It's IMO by far the easiest and most intuitive way to parse any object, especially considering parsers are monadic, which means you can use LINQ to easily compose parsers.

  • @T___Brown
    @T___Brown Год назад

    Awesome ty. This is waaaaay overdue. Doing this with generics is painful and not really possible

  • @bartekm3878
    @bartekm3878 Год назад

    Heck yeah! The puns are back! ❤

  • @hanspetervollhorst1
    @hanspetervollhorst1 Год назад +10

    The span part is imo way more interesting than the interface and abstract static stuff

  • @waynehamberg9248
    @waynehamberg9248 9 месяцев назад

    Hey Nick. What software are you using to do your screen presentation with your picture as part of the production?

    • @oralitical
      @oralitical 5 месяцев назад

      I didn't see a reply, but it looks like the type of thing that can be done in OBS Studio.

  • @JVimes
    @JVimes Год назад

    Favorite thumbnail

  • @DaliborHomola
    @DaliborHomola 11 месяцев назад

    Does somebody know if Complete Nick Chapsas Course Bundle will get all future courses? Please ☺ I'm thinking of buying it...

  • @gunnarliljas8459
    @gunnarliljas8459 Год назад +4

    Nice. Wouldn't call that extension "Parse" though, since the string isn't parsing, it's being parsed.

  • @deathpax
    @deathpax Год назад

    Is there anything that would be similarly performant for binary parsing?

  • @F1nalspace
    @F1nalspace Год назад

    Awesome! This is actually pretty useful but comes far too late, because i already implemented something similar in our production code bases - implemented in hundres of classes/structs.
    But when we switch to .NET 7 (we are currently at NET 6), we may drop to this method instead. Wait, what is the '!' operator for s!.Split(',');? WIll this throw an exception when s is null?

    • @theMagos
      @theMagos Год назад +2

      You're telling the compiler: "s is never null, trust me, so stop giving me those null reference warnings..."

  • @efrenb5
    @efrenb5 Год назад

    Does System.Text.Json automatically use the IParseable interface? I'd love to get rid of som of the JsonConverters I've had to build.

  • @theloststarbounder
    @theloststarbounder Год назад

    Nice

  • @xybersurfer
    @xybersurfer Год назад

    abstract static members. that's nice. it was about time to be honest

  • @theonlywallrus
    @theonlywallrus Год назад

    just curious, what are you beginning to type when you are setting a default parameter? You start typing `format = by`, but then you backspace and type null. You did it twice haha

  • @TheMCPepo
    @TheMCPepo Год назад +6

    Hi Nick! I'm having kind of a hard time understanding where would you use in real life delegates and events, as we as covariance and contravariance. Do you have anything on your videos on this? Great video as always!

  • @Ristogod
    @Ristogod Год назад

    How does the IFormatProvider play into your custom parse logic?

    • @phizc
      @phizc Год назад

      In the case of ints it wouldn't, but for doubles, some locals use period and some use comma as the decimal separator. Not to mention all the different date/time formats.

  • @ondrejjakub
    @ondrejjakub Год назад

    nice

  • @arodrig10
    @arodrig10 Год назад

    Nice "random" number you chose 😳🤣

  • @tmcheah
    @tmcheah Год назад +1

    "Random number"
    Casually type in "69"
    😂😂

  • @DM-rc8sp
    @DM-rc8sp Год назад

  • @mynameisshadywhat
    @mynameisshadywhat Год назад

    Just parsing the time

  • @phizc
    @phizc Год назад

    I knew about this, but I didn't know the out parameter of the TryParse methods came after the IFormatProvider parameter. That's pretty dumb IMO, since then you can't have a default null vlue, and the user needs to pass null..
    int.TryParse( "20", null, out var value )
    vs
    Int.TryParse( "20", out var value )

  • @Eric19850704
    @Eric19850704 Год назад +1

    Thanks!

  • @IMarvinTPA
    @IMarvinTPA Год назад

    I really wish there were a GetParse(inputString, optional DefaultValue ) where failures return the default value.

    • @tekozlofiu
      @tekozlofiu Год назад

      I'm probably missing something, but what prevents you to create an extension method just like that?

    • @IMarvinTPA
      @IMarvinTPA Год назад

      @@tekozlofiu I actually already have, but I cannot share them.

  • @MaksMikhnevych
    @MaksMikhnevych Год назад

    Why record, not a strict? What are the advantages and when to use which?

    • @ciach0_
      @ciach0_ Год назад

      records are immutable

    • @theMagos
      @theMagos Год назад

      Record is reference type, like class.

    • @phizc
      @phizc Год назад

      He could have used record struct too.. It's just an example for the parser, so he probably didn't bother. Brevity.

  • @EdKolis
    @EdKolis Год назад +1

    I wonder why it's not spelled IParseable like ICloneable?

  • @johnnm3207
    @johnnm3207 Год назад

    Benchmarks?

  • @kylekeenan3485
    @kylekeenan3485 10 месяцев назад

    Just a random number Nick 😉

  • @Mmss2304
    @Mmss2304 Год назад +1

    Of course the number input used as an example is 69.

  • @mohamedfazrin4172
    @mohamedfazrin4172 Год назад

    When Nick says Random number it means always 69

  • @EdKolis
    @EdKolis Год назад

    6:04 hehe ass pan

  • @zabustifu
    @zabustifu Год назад

    11:52: is it actually a good idea to throw an exception here? I'd just expect false to be returned here, and the result to be set to the default value. On the caller side, having to wrap a TryParse call within a try / catch sounds like it defeats the point of using TryParse in the first place.

    • @nickchapsas
      @nickchapsas  Год назад +1

      I mentioned this in another reply but no you shouldn’t throw an exception. I did the stupid think of copying from the Parse method but you should return false there

  • @MudzNZ
    @MudzNZ Год назад

    Noice number

  • @othmanekinane2769
    @othmanekinane2769 Год назад +3

    In 09:38, why not just do this ?
    int commaPos = s.IndexOf(',');
    int first = int.Parse(s.Slice(0, commaPos));
    int second = int.Parse(s.Slice(commaPos + 1));

    • @davidtaylor3771
      @davidtaylor3771 Год назад +2

      Try the equivalent for parsing a CSV file with 10 fields and 10 commas per line.
      Then look again at Nick's code. Nick is just giving you a demo, but this stays elegant when you have 10 fields per line of text.

  • @mateuszk4419
    @mateuszk4419 Год назад +2

    "random number"

  • @kyrylovagabond9172
    @kyrylovagabond9172 Год назад +1

    "Just random number" 😅

  • @iGexogen
    @iGexogen Год назад

    About your example - why not just reuse Parse method from TryParse? And in general - is there such use case where logic in Parse and TryParse should be different? Any reason for ms developers to put it on me to implement both methods rather than implement only Parse?

    • @nickchapsas
      @nickchapsas  Год назад +1

      There is a difference actually and I didn't properly show this. TryParse should now throw an exception. Instead it should return either true or false based on whether it could parse the input, so me returning argument exception is wrong there. I should just be returning false. It's just a common .NET pattern.

    • @iGexogen
      @iGexogen Год назад +1

      @@nickchapsas Here's general implementation of TryParse
      try
      {
      result = Parse(s, provider);
      return true;
      }
      catch
      {
      result = default;
      return false;
      }
      I think it's just boilerplate and it is place in single extension method for whole codebase, and only Parse method have to be implemented. Maybe you know use case where it makes any sense to implement both?

    • @user-tk2jy8xr8b
      @user-tk2jy8xr8b Год назад

      @@iGexogen better do it the opposite way: if TryParse returns false - throw

    • @diadetediotedio6918
      @diadetediotedio6918 Год назад +1

      @@iGexogen
      He already said the use case, not throwing exceptions.
      From where did you take this implementation you provided as a 'general implementation'? Because throwing exceptions has a huge cost, it probably is not implemented this way.

  • @TampaCEO
    @TampaCEO Год назад

    You really should overload the method to allow the caller to pass a string, rather than requiring your calling methods to add the .AsSpan() every time. It greatly simplifies your code and does not requie an .AsSpan() function to be called throughout your application.

  • @nacuflavius9457
    @nacuflavius9457 Год назад +1

    why number 69? it's not a random number at all...hmm

    • @valera924
      @valera924 Год назад +1

      Totally random number, there is no any meaning in it :D

    • @phizc
      @phizc Год назад +1

      @@valera924 yup. Like (4,20), or 80085 that he also randomly chooses. I mean, it is random, but there's fewer options than a 4 sided die. 😆

  • @rdmon746
    @rdmon746 Год назад +1

    int.Paws? int.Pause? 😅

  • @cliffwakefield
    @cliffwakefield Год назад

    .NET 8 preview 5, really?

  • @swordblaster2596
    @swordblaster2596 Год назад

    Pretty marginal stuff IMO

  • @a-s733
    @a-s733 Год назад

    seems not realy necessary...

  • @AftercastGames
    @AftercastGames Год назад

    Meh. Kinda cool, but ultimately not terribly useful, because types rarely only have one string representation.
    If you want to create a different type for each representation, I guess this would work, but it just seems that writing a static parse function would be quicker and easier to understand.
    But we’ll see. Maybe I’m just getting old, but adding new language features every month or two seems a bit chaotic, I think. You can’t even start and finish a project before your code is already obsolete. 🙄

  • @liquidcode1704
    @liquidcode1704 Год назад

    bro you lost me 50 million "if we go into that"s ago