The Magic of Breaking Down Your Types in C#

Sdílet
Vložit
  • čas přidán 24. 01. 2024
  • Check out my courses on Dometrain: dometrain.com
    Become a Patreon and get special perks: / nickchapsas
    Hello, everybody, I'm Nick, and in this video, I will introduce you to a C# feature called deconstruction. It is a really cool feature that can help you write better code.
    Workshops: bit.ly/nickworkshops
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: github.com/Elfocrash
    Follow me on Twitter: / nickchapsas
    Connect on LinkedIn: / nick-chapsas
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

Komentáře • 125

  • @DeserdiVerimas
    @DeserdiVerimas Před 3 měsíci +136

    You can also nest deconstructions. So, for example, you can change that DateTime example to ```var (date, (hours, minutes, seconds)) = DateTime.Now;```, which makes things a lot more descriptive than many parameters, imo

  • @jamesbennett5421
    @jamesbennett5421 Před 3 měsíci +25

    The example of KeyValuePair deconstruction on the “foreach” makes this whole video worth it!

    • @pdebie1982
      @pdebie1982 Před 2 měsíci

      But why? Which problem does it solve? It isn't a lot of work or hard to writeout objectName.Key or objectName.Value.

  • @MatinDevs
    @MatinDevs Před 3 měsíci +42

    4:25 "couple of random numbers" is the biggest lie you've ever told in your life 😂

    • @martink.7497
      @martink.7497 Před 3 měsíci +11

      Nah, he just has really bad seed generator.

    • @Andrew90046zero
      @Andrew90046zero Před 3 měsíci

      heh! He does that all the time :P

    • @Velociapcior
      @Velociapcior Před 3 měsíci

      @@martink.7497 I mean his SEED is in his... you know where

    • @kp_xcess
      @kp_xcess Před 3 měsíci

      @@martink.7497 Very clever one, I like it. Also within the context of this video there's actually a second joke hidden in there too. Not sure if you already intended that or not :)

    • @martink.7497
      @martink.7497 Před 3 měsíci

      ​@@kp_xcess Not sure if we think the same thing, but he always has some joke in the video ;)

  • @aderitosilvachannel
    @aderitosilvachannel Před 3 měsíci +13

    I remember the announcement of deconstructors, when they first came out, but I forgot they even exist. I think they're cool, actually, but I guess I didn't pay enough attention to them, maybe because I haven't seen many examples myself where they could be useful. Now that you brought them to my attention, I think I will start paying more attention on where I could be using them more. Thanks! Great video!

  • @lordmetzgermeister
    @lordmetzgermeister Před 3 měsíci +6

    Deconstructing DateTime can be really handy, I didn't know about it.
    Also a note - both Visual Studio and Rider have quick actions for generating deconstructors, so we don't have to remember the exact duck typing syntax for this.

  • @Fred-yq3fs
    @Fred-yq3fs Před 3 měsíci +9

    interesting. I use deconstruction on tuples, but did not know the other usages and features. I'll try to use it more.

  • @path_selector
    @path_selector Před 3 měsíci +2

    awesome video. love these short and focused videos

  • @nikolayrogchev9628
    @nikolayrogchev9628 Před 3 měsíci

    Awesome stuff, every time I learn something from you, keep up the good work

  • @der.Schtefan
    @der.Schtefan Před 3 měsíci +29

    a great deconstruction is overloading string arrays. That way you can access the results of a string.Split operation

    • @t-moty
      @t-moty Před 3 měsíci

      What about a non-predetermined splitting character?

    • @der.Schtefan
      @der.Schtefan Před 3 měsíci +1

      @@t-moty the thing would read var (a,b,c) = "xxx".Split(",") with "," being the default. a,b,c, woudl be stirngs, you can do something else for "the rest" if you want, but in most cases i'd just stuff the rest into c unsplit (since that would be an error)

    • @alexisfibonacci
      @alexisfibonacci Před 3 měsíci

      @@der.Schtefan I think we have the new spread operator for that?

    • @vyrp
      @vyrp Před 3 měsíci +3

      I think it's improbable the .NET team will ever add array deconstruction, because the number of elements is unknown at compile time.
      In the example above, `a` will be "xxx", but will `b` and `c` be?
      Instead of deconstruction, you can use pattern matching:
      ```
      string numElements = "xxx".Split(',') switch
      {
      [] => "0",
      [var a] => "1",
      [var a, var b] => "2",
      [var a, var b, .. var rest] => "3 or more",
      };
      ```

  • @charles_kuperus
    @charles_kuperus Před 3 měsíci +8

    Nick, I definitely think that the Deconstruct method is not often enough used and I hope this video would give other developers the option of using this feature more.

    • @jfpinero
      @jfpinero Před 3 měsíci

      Here's one dev that will start using this feature more!

    • @joshpatton757
      @joshpatton757 Před 3 měsíci

      Yeah, this was a completely new one to me, I had no awareness of it, but I see quite a few opportunities here.

  • @osr2004snd
    @osr2004snd Před 3 měsíci +2

    Really useful to replace complex DTOs.

  • @klausbjornjensen
    @klausbjornjensen Před 3 měsíci

    Thanks for sharing... nice to know.

  • @sanderqc
    @sanderqc Před 3 měsíci +1

    Content as allways great. 🎉 Why first random int is exact 69 for You? 😅

  • @jamienordmeyer4345
    @jamienordmeyer4345 Před 2 měsíci

    I love that you can do this... but I REALLY wish that they would have just made it a part of the syntax, and have it look closer to JavaScript (I LOVE the way that JavaScript/TypeScript supports deconstruction). So maybe a syntax like this where I can just pull the fields I need without defining a specific Deconstruct method:
    var { FirstName, LastName, birthdate: Birthdate } = person;
    -- or --
    var {FirstName, LastName, Birthdate as birthdate } = person;
    Syntactical sugar, of course. The compiler would just compile it to:
    var FirstName = person.FirstName;
    var LastName = person.LastName;
    var birthdate = person.Birthdate;
    But I'll take what I can get, and having this at all in C# is still super nice!

  • @billy65bob
    @billy65bob Před 3 měsíci

    I remember having to add my own Deconstruct method for the dictionary's KVP.
    Was such a massive oversight... and I think that's still the case if you're stuck with .NET 4.x.

  • @fakhrulhilal
    @fakhrulhilal Před 3 měsíci

    Amazing. I know deconstruction magic since record introduced. But creating from extension method is new for me.

  • @kevman2296
    @kevman2296 Před 3 měsíci

    Records are awsome. I use them a lot for DTOs but this use case is also amazing

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b Před 3 měsíci

    I wish there was some support for sum types, i.e. multiple Deconstruct_s returning bool. Having that functionality one could possibly switch on an Option type like `value switch { (var value) => TransformSome(value), () => TransformNone() }` provided a 1-tuple and 0-tuple deconstructions are made possible. Still not good enough to deconstruct an Either type though.

  • @x0rld159
    @x0rld159 Před 3 měsíci

    I always use the Dictionnary deconstructions to named properly my key/value

  • @fifty-plus
    @fifty-plus Před 3 měsíci +2

    Use it quite a bit, it's very useful, not just in loops but to save dotting into the variable later in a method. Makes code a lot cleaner.

  • @s.hosseinhosseini8330
    @s.hosseinhosseini8330 Před 2 měsíci

    Good one.

  • @itaylorm
    @itaylorm Před 3 měsíci

    Thanks is awesome, thank you

  • @d3vil5oldier
    @d3vil5oldier Před 3 měsíci

    I did know about this but never used. I liked the datetime example that will help on my current project. Many thanks.

  • @AlexxXRecorD
    @AlexxXRecorD Před 17 dny

    Nice feature, but I think, necessity to use it appear not often. Thanks for video!!!

  • @ayoko5161
    @ayoko5161 Před 3 měsíci +3

    It is weird to have a method with a specific name 'Deconstruct' on an object, that translates the object directly without the declaration of a tuple. For instance, if I declare a method that is named 'Deconstruct' when I work on a 3d application, then this method name might be ambigous with object deconstruction. In my opinion, this feature leads to mentally overhead you need to remember, but you would not expect. Therefore I think it does not support code to be clean, if it is used wrong. To use this feature in a good way, it should be really obvious like in the example with key-value-pairs. Best way would be to use a method, which returns the tuple.

  • @MixturaLife
    @MixturaLife Před 3 měsíci

    What I don't like about this object deconstruction is that it deconstructs based on the position of parameters in the Deconstruct method. It could be error-prone in cases when parameters share the same type. Pity that there is no option to specify parameter names similar to how I would have done it in methods/constructors.

  • @idk_just_will
    @idk_just_will Před 3 měsíci +1

    I’ve used deconstruction for JS for a long time, pretty stoked to learn it’s available in C# too! I feel like KVP and custom records seem ideal. Maybe also some larger classes like Request would be nice to strip off just relevant pieces like Host and Query Params, but it doesn’t seem like you can just take what you want like JS, unless there’s a way to do it like a named parameter.

    • @kabal911
      @kabal911 Před 3 měsíci

      Indeed, how this works on JS objects is super useful and nice, and can be used everywhere, even as function parameters.

  • @88spaces
    @88spaces Před 3 měsíci

    I'll use the dictionary for each example. That's helpful. Thanks, Nick.

  • @xRealHackerx
    @xRealHackerx Před 3 měsíci

    That mustache says a lot about your favorite number 😁

  • @figloalds
    @figloalds Před 3 měsíci

    Not many things in my day-to-day have obvious de-constructions, and when they do I don't even write a Type, I just straight up use tuples

  • @RagtaouiIssam-yb1nc
    @RagtaouiIssam-yb1nc Před 3 měsíci

    Hi I need some help. I am listening to a socket for stock data, but sometimes when the data is very fast I get a lot of queueing and delay. I am using c#, I think the size of my buffer is very small. Do you have some suggestions on how to increase the size of the buffer?
    And thank you very much for all your videos.

  • @voidmice1669
    @voidmice1669 Před 3 měsíci +1

    Can you use deconstructors in switch expressions especially for custom classes?

    • @realtimberstalker
      @realtimberstalker Před 3 měsíci +2

      I don’t know, but it’s unnecessary as you can already switch over a type’s properties with pattern matching.

  • @stxnw
    @stxnw Před 3 měsíci

    reasons why i don’t use this is because my codebase linter disallow using var and unpacking in c# looks terrible. i usually use it in a foreach loop where it looks a lot more readable

  • @kp_xcess
    @kp_xcess Před 3 měsíci +1

    It's probably because I haven't had a clear use case for deconstructors to date, but I don't really see where using them is an advantage over simply using a class' members. Also, when deconstructing them into local variables, does that not cause additional allocations on the stack or even heap?

    • @pdebie1982
      @pdebie1982 Před 2 měsíci

      I'm also not sure which problem is being solved with deconstruction.

  • @QuAzI_NODE
    @QuAzI_NODE Před 3 měsíci

    Maybe it would be useful for some HttpResponse where you need to check the status before getting result

  • @musichobbylife
    @musichobbylife Před 3 měsíci

    It would be great if you could scope the variables e.g. var (date, time ) = new DateTime() { // code here can access date time } // code here does not see date or time. This makes it really easy to both review the code and free unused variables. I am aware this could be done by wrapping the block itself in { }.

  • @wyattcallister2388
    @wyattcallister2388 Před 3 měsíci

    Wow wow wow! That is cool!

  • @RockTheCage55
    @RockTheCage55 Před 3 měsíci +1

    cool i do this in javascript all the time. I didn't know this was possible in c#

    • @asedtf
      @asedtf Před 3 měsíci +2

      The JS thing is different and definitely more powerful.
      Deconstruction in C# is nice but it's not JS

  • @softwaretechnologyengineering

    What happens to the reference of the class with the deconstructor if the deconstructor returns an object and the class with the deconstructor goes out of scope but the object remains in scope? Will the original be garbage collected or will it remain in memory?

  • @Spid88PL
    @Spid88PL Před 3 měsíci

    Mmm, interesting thing :) Thanks

  • @andreaskarz
    @andreaskarz Před 3 měsíci

    Very cool, the excample with the dates are super

  • @foxred2380
    @foxred2380 Před 3 měsíci

    Hello, can you make demonstration video about SAST pls

  • @pdebie1982
    @pdebie1982 Před 2 měsíci +1

    Still not sure why you should use object Deconstruction. What problem is it trying to solve? I mean, it isn't complex to write out Point2D.X or keyvaluepair.Value.

  • @garcipat
    @garcipat Před 3 měsíci +2

    I would like if deconstruction would work for linq expressions of objects. Like keyValuePairs.Select((key,value) => ....). Sadly it doesnt

    • @funkwurm
      @funkwurm Před 2 měsíci

      With your syntax the compiler can't know whether you mean to deconstruct or whether you want the index of the item in the keyValuePairs into the value parameter. But yes you could imagine a syntax like keyValuePairs.Select(((key, value), index) => $"Item at {index} has key {key} and value {value}");

    • @garcipat
      @garcipat Před 2 měsíci

      @@funkwurm you are right. Maybe that even already works, didny try that yet

  • @badderborroda4972
    @badderborroda4972 Před 2 měsíci +1

    What is an actual use for deconstruction though? I don't personally think (year, month, day) is cleaner than just using date.Year, date.Month, date.Day, and presumably deconstructing is doing more under the hood than just referencing the variable on the class so it will be marginally slower?
    For me it's worse readability and even if negligible worse performance

  • @longvungoc260
    @longvungoc260 Před 3 měsíci

    how to access view deconstructor method like Nick, I want to know its keyboard shortcut

  • @MichaelBattaglia
    @MichaelBattaglia Před 3 měsíci

    Can you add deconstructors to sealed classes?

    • @vyrp
      @vyrp Před 3 měsíci

      Yes, as extension methods, like Nick showed in the video.

  • @mirkogeffken2290
    @mirkogeffken2290 Před 3 měsíci

    Deconstructors are only good with folks that use good variable names. It’s why I love var. Help those after you are gone to comprehend what you left.

  • @body_web_life8497
    @body_web_life8497 Před 3 měsíci +3

    Hi Nick!
    Great video.
    I have a question , if you can add aliases in the deconstructive parameters.
    If yes how this implemented.
    Thanks in advanice , Keep it up 🙌🙌🙌

    • @PublicVoidFoo
      @PublicVoidFoo Před 3 měsíci +2

      You can name your deconstructed variables as you like. They don't need to match the parameter names of the Deconstruct method. It matches based on position.
      For example:
      var (myKey, myValue) = new KeyValuePair("foo", 420);

    • @body_web_life8497
      @body_web_life8497 Před 3 měsíci

      @@PublicVoidFoo Ok thanks !! But if we are talking about a class DateTime that have properties day etc. If i want to set an alias currentDay how the Deconstruction understand that I refer to day property?

  • @meisamhashemi4363
    @meisamhashemi4363 Před 3 měsíci +1

    muscle memory typed that number

  • @BernhardMillauer
    @BernhardMillauer Před 3 měsíci

    Dear Chapsas, I really appreciate your work and engagement to bring knowledge to the people. May I ask you very politely to add warnings to the extensions you teach? Like the Task the foreach-range extension some time ago which is kind of "clever" but hard to grasp if you're new. In addition to the "hidden" dept you introduce with such code, refactorings with tools like resharper break at some point because these tools just don't know how "clever" you were with your code extensions. So please, keep going with these interesting ways to use c# and show what's behind the curtain, yet add a warning to your fellow viewers that, if you leave the standard-path, you chose to travel at your own risk. Thank you very much!

  • @olyazhulanova8028
    @olyazhulanova8028 Před 3 měsíci

    nice

  • @Sander-Brilman
    @Sander-Brilman Před 3 měsíci +2

    I initialy thought you were talking about the destructor. but this is also very cool

    • @fifty-plus
      @fifty-plus Před 3 měsíci +3

      I think you meant destructor, no?

    • @Sander-Brilman
      @Sander-Brilman Před 3 měsíci

      @@fifty-plus yea i mean that, i always get them confused 😅

  • @klaxxon__
    @klaxxon__ Před 3 měsíci

    It's annoying how you can't deconstruct on the left side of a lambda arrow (eg. a Select over enumerable of KeyvaluePairs would let you take key and value on the left side of the arrow). I use that in Typescript all the time. You also can't deconstruct in the inline variable declaration when taking a value from an out parameter of a function you are calling.

  • @inzyster
    @inzyster Před 3 měsíci

    That’s super useful. Is the duck typing magic all compiler or is there some kind of performance penalty for using this?

    • @asedtf
      @asedtf Před 3 měsíci +1

      It's not duck typing in that sense. There's a Deconstruct method behind this. You're just calling the method. If I misunderstood the question, then the answer is "yes it's all compiler magic"
      The only penalty is on the scale of doing the deconstruction into separate variables, but you're already paying that cost in general. The only time it matters is when you Deconstruct to only access one or two properties out of hundreds. Good luck even having a Deconstruct method in a type like that

    • @inzyster
      @inzyster Před 3 měsíci

      Thanks, that’s exactly what I was curious about 🙂

  • @stephenyork7318
    @stephenyork7318 Před 3 měsíci

    Why are they getting away from interfaces? For something to be usable in a foreach you need the class to have an interface method implemented. For disposable you need to implement disposable. I would have thought a feature like you’re showing would require the interface to implement IDeconstructible. I noticed that middleware classes also don’t implement an interface. Shirley it’s less efficient for the language to have to reflect the instance to see if they have the expected method?

    • @necrokora7688
      @necrokora7688 Před 3 měsíci

      It is not reflected but lowered

    • @JamieTwells
      @JamieTwells Před 3 měsíci

      Because the signature of the interface would limit the types and number of parameters you can deconstruct. He only shows deconstructing two parameters here but you can do three or any number (more than 1).

  • @jessebitch6227
    @jessebitch6227 Před 3 měsíci

    Nick we are waiting for .NET Roadmap 2024. :D Cheers

  • @boxacuva
    @boxacuva Před 3 měsíci

    The one issue i have with this is that deconstruction for DateTime is culture specific.

  • @garcipat
    @garcipat Před 3 měsíci

    Sadly i rarly found any usecase for this.

  • @kenbrady119
    @kenbrady119 Před 2 měsíci

    Isn't this just an implicit cast operator?

  • @gavinlangley8411
    @gavinlangley8411 Před 3 měsíci

    Async functions cannot access functions with out parameters, doesn't that limit the use-cases for this quite a lot?

    • @asedtf
      @asedtf Před 3 měsíci

      Why would your Deconstruct method need to be async? That implies you're doing far more than deconstructing

    • @gavinlangley8411
      @gavinlangley8411 Před 3 měsíci

      @@asedtf The point is that the deconstruction cannot be used within a function which is async. If the question is why should a function be async then that's a technique for server resource utilisation. It's quite a big limitation.

    • @kp_xcess
      @kp_xcess Před 3 měsíci +1

      This is not true. Methods that are async themselves can perfectly use other methods containing out parameters.

    • @asedtf
      @asedtf Před 3 měsíci

      @@gavinlangley8411 what are you on about? Yes it can
      Source: *I've literally done it*
      Async functions *cannot themselves* have out or ref parameters. They can most certainly call and use methods that use those.

  • @AddictOfLearning
    @AddictOfLearning Před 3 měsíci

    I think this is neat, but I can't think of any real world use that I would use this for.

  • @zagoskintoto
    @zagoskintoto Před 3 měsíci +7

    I feel no one gives you enough credit for the commitment to use 69 everywhere, even when initializing your Point2d. So here it goes. Nice

    • @PublicVoidFoo
      @PublicVoidFoo Před 3 měsíci

      420 didn't make an appearance this episode 🍀

  • @ravikumarmistry
    @ravikumarmistry Před 3 měsíci

    69 is your favorite I think

  • @Namynnuz
    @Namynnuz Před 3 měsíci

    Finally, well welcomed TypeScript feature implemented in C#.

    • @evancombs5159
      @evancombs5159 Před 3 měsíci +1

      Deconstructors have been around for a bit at this point, coming in with C# 7

  • @grozoff
    @grozoff Před 3 měsíci

    Hello Python

  • @ralmslb
    @ralmslb Před 3 měsíci

    One issue I worry about deconstruction, is the added GC pressure vs accessing the values directly.

    • @ara849
      @ara849 Před 3 měsíci +1

      Why would it add additional pressure to GC?

    • @diadetediotedio6918
      @diadetediotedio6918 Před 3 měsíci

      It has no added GC pressure because the tuples it uses for deconstruction are structs, they are (in this case) allocated on the stack.
      *** Correction, I totally forgot about this ***
      It does not use value tuples either, it is just a method that uses a bunch of 'out' params, so you will not be allocating nothing either way.

    • @ralmslb
      @ralmslb Před 3 měsíci

      ​@@diadetediotedio6918I would say it depends on the parameter type.
      Because if I use for example a custom object or any other ref type, I would expect an allocation from the out parameter, even if just to have an object that has the memory address of the data it contains.
      Which still forces GC to clean it up eventually.
      I highly doubt that this acts the same way as for example stackalloc.
      I guess I will need to run some tests to be sure.

    • @diadetediotedio6918
      @diadetediotedio6918 Před 3 měsíci +2

      ​@@ralmslb
      No, not really. This do not depends upon the parameter type, because the practical difference between a reference type and a value type in this context is merely how it is represented in the stack. If you out a struct, it will be copied entirely by the processor into the out param (assuming no optimizations), and if you out a class it will just copy the 8 byte pointer into the out param (assuming a x64 architecture), no heap allocations would be made in this context. Heap allocations (the matter of GC) occur only when you create a new class instance or box a struct, otherwise it is just overwritting memory everywhere around.

    • @ralmslb
      @ralmslb Před 3 měsíci

      @@diadetediotedio6918 You're right, I did some benchmarks, isolating the base Class to just have the decomposition and it causes no GC (params were an int and a String).
      I was confused thinking that even if you are copying the reference, that an object with that reference would be created, that would result in GC allocations, which even if it's happening, it's being cleaned out when existing the method context and not by GC.

  • @ILICH1980
    @ILICH1980 Před 3 měsíci

    Nick 69 - oh my ;-)

  • @anar.bastanov
    @anar.bastanov Před 3 měsíci +1

    Hello

  • @MatinDevs
    @MatinDevs Před 3 měsíci

    this number is cursed 😂

  • @asteinerd
    @asteinerd Před 3 měsíci

    Honestly it's kinda pointless unless you have the additional flexibility of the spread operator putting "the rest" of the object into subset type like Typescript does.
    The heap/stack could create a ref just hides class members that have already been implicitly referenced; make it something akin to a read-only struct to avoid recreating the object every time a local variable is created using decontruction.
    When C# get Pick and Omit capabilities than it will be a powerhouse of simplicitiy allowing ultraportable type-ref libraries akin to what we see in TypScript.

    • @diadetediotedio6918
      @diadetediotedio6918 Před 3 měsíci +2

      I don't see how it does not having what you like make it 'pointless', it is pretty useful in some scenarios for clarity even without this resource you are mentioning. It with it, but it does not render the actual implementation .

    • @asteinerd
      @asteinerd Před 3 měsíci

      ​@@diadetediotedio6918 it's a half-baked syntax-sugar feature that's relatively unessesary in a language that supports tuples and delegates outright that can accomplish very similar things.
      Plus I don't really see C# using it anywhere other than data-type structs with values that are expressed at invoke; versus classes that could potentially compute and mutate after intialization and during run-time, meaning "out" would need to be switched out with "ref" to stop the stack/heap from replicating the object every time the variable/local is used.
      It's a really cool feature as-is; but I don't see a point to it. It doesn't make coding faster, it doesn't optomize the code doing it this way, it's not cleaner or legible that adding a dot and variable name on the next line.
      ----
      I'm sure I'll come around to liking it once it's fully implemented and non-scripting use-cases are provided for it. But I stand by my 'pointless' opinion of it.

  • @oislek34
    @oislek34 Před 2 měsíci

    Get to the point man, stop counting seconds for $$$