Here is What Hides in Every C# Record (And How You Can Use That)

Поделиться
HTML-код
  • Опубликовано: 13 сен 2024

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

  • @zoran-horvat
    @zoran-horvat  Год назад

    Become a patron and get access to source code and exclusive live streams: www.patreon.com/posts/here-is-what-in-81378321

  • @AlexUkrop
    @AlexUkrop 2 года назад +9

    I've listened all your courses on Pluralsight and completely changed my code view and programming style. All my new code is fully functional now and almost no errors except may be logical errors. Your courses inspired me to move to "functional programming" and I really happy with new code style. IoC + Interfaces + Functional Programming == Power. Thanks a lot.

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

    What an amazing explanation for records.I would love real world scenarios of where these could shine instead of a regular class

    • @zoran-horvat
      @zoran-horvat  Год назад +1

      More examples will come in future videos, showing records as part of larger models.

  • @StevenJAckerman
    @StevenJAckerman 2 года назад +2

    Very nice overview Zoran - thank you !

  • @kasarci
    @kasarci 2 года назад +2

    Brilliant explanation! Thanks for the great content. Much appreciated.

  • @sunnypatel1045
    @sunnypatel1045 2 года назад +2

    Thank you so much

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

    Fair comment on DateOnly type 😁

  • @francoismouchati8189
    @francoismouchati8189 2 года назад +3

    I use records a lot for DTOs. Not for value objects though as I like my ctor to be private and only expose a static ctor.

    • @zoran-horvat
      @zoran-horvat  2 года назад +1

      If you moved on to a more functional design, you would discover true value of records.

  • @milanmladenovic
    @milanmladenovic 2 года назад +2

    Hvala Zorane.

  • @amarsha4
    @amarsha4 2 года назад +2

    Great video as usual. You mention "vertical compatibility", which is not a phrase I've come across before, and Google doesn't really help. Could you explain this concept please?

    • @zoran-horvat
      @zoran-horvat  2 года назад +3

      That term refers to compatibility of a programmatic element with previous version of code, though I am not sure how widely used it is. In a practical sense, you will want to make such change to one element in code that does not cause observable changes in the way other existing elements in code work. That includes failing to compile, for one thing, but also more subtle, semantical changes, that might make those other elements incorrect after the change. You can imagine it as forcing the new implementation of a class to work correctly with the rest of the software taken from a previous commit. Corresponding term in software development life cycle is backward compatibility.

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

      @@zoran-horvat Good video! "Vertical compatibility" sounds close to Liskov Substituation Principle perhaps? en.wikipedia.org/wiki/Liskov_substitution_principle

  • @Darebit2k1
    @Darebit2k1 2 года назад +2

    Como siempre: excelente explicación. Gracias

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

    Great video!
    Question: would it be wise to use record to store Point representing int values? Since a point can be 2d or 3d i was thinking "record Point(int? X, y, z) and make y and z have default null value we could represent 2d or 3d point and we could use it as a dictionary key (since we can easily compare records)?
    Sorry for a long question but I am trying to figure out a good use case for records in games - here representing grid points.
    Thank you for making all those videos!

    • @zoran-horvat
      @zoran-horvat  Год назад +3

      You should be safe to use records in that way. You can also choose to use a record struct if that would improve performance even further. Record structs differ from common structs in that their equality members are generated at compile time, rather than implemented via reflection as in common structs.

  • @piotrw3366
    @piotrw3366 2 года назад +2

    Great video! Thank you very much Zoran! I have to watch your latest course about C#10 🙂
    If you don't mind me asking it really seems like the *record* type would be more useful with FP /Data-oriented code rather than in OOP? What to you use record type for (if you can suggest some uses) ? Thanks!

    • @zoran-horvat
      @zoran-horvat  2 года назад +6

      Records are functional indeed, but listen, my OO code is mostly functional anyway. You don't need to make your model entirely functional to fit many functional types into it. Any domain concept that behaves like a value is a candidate for a record: Money, document number, name, SSN, plates number, pixel value, sound sample, weight, distance, etc. - there are dozens and hundreds of opportunities, depending on a project size and problem domain.
      C# syntax has been moving in functional direction since v. 7. Records were one of the long awaited features in that way. There are more features we are still awaiting: Discriminated unions, simplified extensions (including extension properties), etc. Look at the improvements to pattern matching - those are all functional to the core. And yet, all that syntax fits naturally into an OO model.

  • @martijngr
    @martijngr 2 года назад +1

    Thanks for the explamanation, really like your way of coding, I am a bug fan. I have one question though, couldn't you also add a new optional parameter to the constructor with the default value set to an empty string?

    • @zoran-horvat
      @zoran-horvat  2 года назад +1

      Good point! Actually, I did that in the next video that relates to records: Nondestructive Mutation and Records in C# ruclips.net/video/m__l58cmiEQ/видео.html

  • @1Eagler
    @1Eagler 10 месяцев назад +1

    How do you save the record to an sql server using mvc core?

  • @nickbarton3191
    @nickbarton3191 10 месяцев назад +1

    There's no way to enforce that only the static factory method is used to construct the record? Pity.

  • @zholinho
    @zholinho 2 года назад +1

    Hi, I am using records for value objects and also for aggregates. Do you think that's a good idea?
    If you have a static factory method where you can do validation, with keyword allows you to bypass validation through the factory method?

    • @zoran-horvat
      @zoran-horvat  2 года назад +2

      The first question, about using records to define aggregates: I think that is not appropriate. Aggregates normally include entities, which by definition have at least two possible equalities - by ID and by content. Therefore, a value-typed model is not appropriate for entities.
      The second question, about validation: You are right there. There is less stress on validation when working with value objects. I even thought whether to mention validation in the video or not. The point is that value can hardly tell whether it is valid, because it can be used in many contexts. You will often validate values in the holding entity and any value that comes in through the with expression would already be validated.
      You can imagine a scalar value - an int, for example. One would never think of attaching validation to the int itself, but rather to the one who assigns that int. Records are allowing us to construct more complex types with the same kind of behavior like a common int.

  • @superpcstation
    @superpcstation 2 года назад

    Thanks for the video Zoran. A little off topic, but are you still working on your beginner C# course?

    • @zoran-horvat
      @zoran-horvat  2 года назад +2

      Yes! There are 17+ hours of materials I have recorded so far, and about 7 hours produced. Some more work remains until the first half sees the light of the day.

    • @superpcstation
      @superpcstation 2 года назад

      @@zoran-horvat Yes!! Can't wait!!

  • @SuvobrotoPal
    @SuvobrotoPal 10 месяцев назад +1

    🙏🙏

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

    Cool

  • @danflemming3553
    @danflemming3553 2 года назад

    I disagree. Records are not much usable for anything but maybe DTOs. They cannot maintain encapsulation due to how 'with' works. Encapsulation is very important.

    • @zoran-horvat
      @zoran-horvat  2 года назад +2

      Wow, wait a minute. That is the 1990s coding style speaking out.
      The record syntax is instituting a practice known for decades, so that programmers don't have to write tons of repetitive code manually, as they did for ages. Programmers, though, DID NOT write that kind of code for DTOs, nor do records serve that purpose well - for one thing, they do not support deserialization.
      And that encapsulation thing - I can just say: no. Property getters do not break encapsulation, nor copy constructors do. That discussion was over in the last century, so far as I remember. It was around Visual Basic 3 when I heard someone bring that issue up the last time.
      Bottom line:
      1. Records are a powerful modeling tool in modern software designs;
      2. Records are not useful as DTOs;
      3. Records and with expressions do not break encapsulation.

    • @danflemming3553
      @danflemming3553 2 года назад

      @@zoran-horvat Huh ? What Visual Basic got to do with the 'with' behavior in C# records?

    • @zoran-horvat
      @zoran-horvat  2 года назад +1

      ​@@danflemming3553 Back to what I said, the last time I heard someone raising that question of a violated encapsulation in these settings was back around 1995 or so, and the question was cleared and dismissed as a well-known fallacy by that time already. It is the result of a fundamentally flawed view on encapsulation.
      And if you wish to speak about Visual Basic, then yes - VB before .NET had full support for what with expressions do today, and code looked line-to-line the same as the corresponding code in C# 8, before with and init setters. That was mid-1990s, too.

    • @danflemming3553
      @danflemming3553 2 года назад

      @@zoran-horvat I honestly don't understand what you're talking about. You say "if you wish to speak about Visual Basic". No, I don't want to speak about VB, you brought it up in your previous reply.
      But I'd like to hear more about what you mean by "fundamentally flawed view on encapsulation". What do you mean by that?

    • @zoran-horvat
      @zoran-horvat  2 года назад +2

      ​@@danflemming3553 For a precise statement, I would need your precise claim. So, please explain: How does 'with' work, which prevents maintaining encapsulation?
      And the general fallacy regarding encapsulation is in believing that exposure of components is somehow related to encapsulation. It is not, because exposing a component of type T is in no way different from having a method that returns an object of type T. And setting a component of type T is in no way different from having a method that receives an argument of type T. None of those itself is violating encapsulation.

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

    🙏🙏