Primary Constructors in C# 12 Explained!

แชร์
ฝัง
  • เผยแพร่เมื่อ 5 ต.ค. 2024

ความคิดเห็น • 71

  • @Kokujou5
    @Kokujou5 ปีที่แล้ว +14

    finally... no longer triplicated code when dependency injection... it's a dream come true. it's so frustrating, first you need them in the constructor, then inside the constructors bvody and secondy you need them as private readonly properties inside your case. triplicated code.
    i was so close to switching all my classes to records just because it was so annoying but now it's finally coming to classes! now i'm happy

  • @mwetzel0
    @mwetzel0 ปีที่แล้ว +14

    I'd take robustness and readability over saving lines of code. But, if this makes (some) code more robust and readable, than I'm all for it. I'm not sure I'll personally use the feature because I see too many cases where it's detrimental (like giving up parameter checking) and I'd rather my code be consistent (versus some using primary constructors and some not).
    I don't think allowing to create a Person with, say, a null name or a whitespace-only name, qualifies as robust. I'd prefer to throw an exception at construction rather than have some hard to track down condition where a bogus property caused a bug elsewhere in time and code.

    • @nayanchoudhary4353
      @nayanchoudhary4353 ปีที่แล้ว

      Conditional attributes should be able to help there. The only thing left would be instantiation honouring the attributes.

    • @nayanchoudhary4353
      @nayanchoudhary4353 ปีที่แล้ว

      Or, use a factory or builder

  • @ignispurgatorius5297
    @ignispurgatorius5297 ปีที่แล้ว +11

    I don't see myself having much use for the example around the logger, because usually that would just mean I have to pass more stuff that I might not need in most cases, so the use case feels a bit forced there. But I can definitely see the use case around having a primary constructor for myself when declaring small classes that are mostly used to shovel data between interfaces. Those will definitely look neater that way.

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว +1

      Yeah I wanted to try to describe the actual feature first before showing it in an app like I did with monkey finder with DI systems in place which is the real win IMHO

  • @aathifmahir
    @aathifmahir ปีที่แล้ว +10

    It would be great, if the c# team adds an option to make fields readonly by using the ReadOnly Keyword in the Primary Ctor

    • @obinnaokafor6252
      @obinnaokafor6252 ปีที่แล้ว +2

      It is being discussed and will be a needed option for Primary Constructor.

    • @chezchezchezchez
      @chezchezchezchez ปีที่แล้ว

      Can’t you just read from it only, and not write to it? 😂

  • @samuelmbah8789
    @samuelmbah8789 ปีที่แล้ว +4

    Nice video James. For someone who's written C# for less than a year, this feature looks cool to me 😄. I'll try it out

  • @waleedbensumaidea3947
    @waleedbensumaidea3947 ปีที่แล้ว +1

    Thank you so much James🌹. This is very helpful

  • @grumpydeveloper69
    @grumpydeveloper69 ปีที่แล้ว +3

    I see a benefit for structs and records where the parameters are the data being stored. But, what about constructors that have move than just assignments, and have calls to say a private initialisation method. That is not compatible with primary constructors right?

  • @krccmsitp2884
    @krccmsitp2884 ปีที่แล้ว +1

    I'm indecisive whether I like it and will use it, or not. What bothers me mostly is the different behavior to records for the same syntax.

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว

      Yeah, compatibility has its limitations. I haven’t really moved anything to records so for me I live this where it makes sense in my classes.

  • @HOSTRASOKYRA
    @HOSTRASOKYRA ปีที่แล้ว +1

    When will they finally add a constructor method, without a class name?

  • @MohammadNikravan
    @MohammadNikravan 10 หลายเดือนก่อน

    Assigning the primary constructor to a fullset property results in having two fields in your class - one for the field and one for the primary constructor. Unfortunately, we can't make the generated field as read-only in the primary constructor. If we assign parameter to a property it might cause the object to consume double the memory or at least bug prone as we have to make sure which one is used in the class. If you bypass the primary constructor to the parent, the field will exist in derived class too! This feature can be quite confusing, and I wish there was an option to disable it completely to prevent our team from using it.

    • @JamesMontemagno
      @JamesMontemagno  10 หลายเดือนก่อน

      the paramter isn't a field... you can't access via "this." for example. If you want something to be read only you would want to make it read only field..... it is a constructor just like any other constructor

  • @WhiteCapix
    @WhiteCapix ปีที่แล้ว +1

    To be honest looks neat, but when you replaced the MonkeysViewModel with the primary constructor we don't have any longer the whole code on the file in front of us, we need to scroll sideways, which for me is not super. We could get some line breaks and still be fine, I would say.

  • @ryanye6938
    @ryanye6938 ปีที่แล้ว +1

    dude you gonna loooooove typescript

  • @Sindrijo
    @Sindrijo ปีที่แล้ว

    Does this mean we also get expanded generic constraints for constructor signatures?
    Before you could only constrain a generic to have a default constructor with no params e.g. SomeClass where T : new()

  • @ahmad.mozaffar
    @ahmad.mozaffar ปีที่แล้ว +1

    Thanks

  • @scotty3024
    @scotty3024 ปีที่แล้ว +7

    C# is becoming more like Kotlin every day

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว +2

      I feel like there is a lot of cross over between languages and that is a good thing IMHO

  • @dotnetdevni
    @dotnetdevni ปีที่แล้ว

    Its def a game changer but did you no about the = null trick on your interfaces I didnt until a more senior then myself pointed it out.

  • @NemanjaSimovic
    @NemanjaSimovic ปีที่แล้ว

    Looks like you missed to say that primary constructor creates private field with the same name as its parameter. Nice video thou. Thanks.

  • @philippelhaus
    @philippelhaus ปีที่แล้ว +1

    Useful

  • @gds03_
    @gds03_ ปีที่แล้ว

    what about the underscore convention for variables, specially private ones? defining a area of variables with _ to me helps a lot!

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว +1

      You can name them whatever you would like :)

    • @gregdennis6094
      @gregdennis6094 ปีที่แล้ว +1

      @@JamesMontemagno but then you have ctor params with underscores. Params don't have underscores by that convention.

  • @stephenmiller4948
    @stephenmiller4948 ปีที่แล้ว

    This is pretty cool, James! But… How does this work with DI? The DI container had to have been getting the class instantiation signature from the constructor. Does this require a newer version of the container?

    • @NiamaImia
      @NiamaImia ปีที่แล้ว

      Guess it still converts into constructor and can be obtained from class metadata with no difference, so nothing changes for DI

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว

      It works exactly the same today… it’s just a constructor :)

  • @dmitrymezinov9238
    @dmitrymezinov9238 ปีที่แล้ว

    hmm... interesting feature, but where to check constructor params (for null, as example) and throw exceptions if necessary? isn't that common practice to do such in constructors?

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว

      I think nowadays you would just turn on null ability and mark things that can and can’t be null. Or check when you are using things in a method.

  • @mtranchi
    @mtranchi ปีที่แล้ว +1

    like it!

  • @kolesplace
    @kolesplace ปีที่แล้ว

    I love these new features. If I'm hopeful my employer will adopt C# 12 by 2030 😂😂

    • @JackLyons00
      @JackLyons00 ปีที่แล้ว +1

      I feel your pain

  • @hj.0301
    @hj.0301 ปีที่แล้ว

    does it work with mapster's MapToConstructor?

  • @damiank6566
    @damiank6566 9 หลายเดือนก่อน

    you dont have to add "?" to strings - they are reference types and are nullable anyway

  • @Eirenarch
    @Eirenarch ปีที่แล้ว +1

    The savings are not worth it the insane scoping rules. i'd rather have them port the records primary constructors to classes so at least they can be used to declare properties

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว

      The problem I think is records are immutable and doing the same for classes would break a bunch of things. They review all proposals and implementations in the open so provide the feedback on GitHub!

    • @Eirenarch
      @Eirenarch ปีที่แล้ว

      @@JamesMontemagno I've done so, as have hundreds of other people who dislike the proposal

  • @eriknyk2k
    @eriknyk2k ปีที่แล้ว

    I can see that it's borrowed from kotlin and I love it

  • @MartinMaat
    @MartinMaat ปีที่แล้ว +2

    So first they introduced multiple property styles which was undesirable and stupid (as if anyone would want their language to facilitate mixing different styles that do the exact same thing, we don't mix formatting styles, we didn't need this). They must have figured you still had too much opportunity to focus on your coding logic. You would rather use a part of your brain to figure out different constructor styles as well, would you not? Let's clutter the class declaration some more, just the class name, a base class and a number of interfaces is way too easy, let's throw in some arguments for no ffin' benefit at all. Way to go C# designers.

    • @nielshoogev1
      @nielshoogev1 ปีที่แล้ว +1

      Personally, I use records with required and init for objects that only contain data, and I use primary constructors for classes that do processing and participate in DI. I am very happy with these features and I am glad the C# designers added them.

  • @ak_nex
    @ak_nex ปีที่แล้ว +1

    This primary constructor sucks...
    1. Most people prefer private field names with underscores. How stupid it would be to have smth like this: Person(string _name)...
    2. And what about records? Their primary constructors behave differently. The parameters are not private fields but properties with "get" and "init" modifiers.
    It would make more sense to have the same implementation in both cases then

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว

      Don’t have to use them if you don’t like them… just like any feature. For me, I can see me using them in a high majority of classes I have today.

    • @ak_nex
      @ak_nex ปีที่แล้ว

      ​@@JamesMontemagno in case when you need to change a class to a record, e.g. to copy properties using 'with', you might forget about the incompatibility of primary constructors and expose private fields as public properties.
      I'm sure each of us had the case at least once.
      So, this is my biggest concern

  • @truebzyq
    @truebzyq ปีที่แล้ว +13

    Coding is not about "saving lines of code" but about readability, so all sexy blink blink code shortcuts are simply making language less readable, and less bugproff, and imagine that right now you are start learning programming in 2023 and someone just give you that class, with primaru constructor but you need to learn at first what constructor is, and the question is why? Why you have used 'l' in seconda constructor? Any problems with the same property name? Offcourse and then try to described it to a person that that just start learning programming. Its simply a nightmare.

    • @cethien
      @cethien ปีที่แล้ว +3

      it is pretty readable and "saving lines of code" also makes your code less prone to bugs

    • @obinnaokafor6252
      @obinnaokafor6252 ปีที่แล้ว +1

      So, every other languages that have primary constructor are less readable? Features such as this make C# more readable and succinct and less prone to errors.

    • @ВладимирМакайда-м9т
      @ВладимирМакайда-м9т ปีที่แล้ว +2

      Explain to your beginner why in all classes constructor parameters are tediously assigned to class fields, readonly:) Boilerplates occupied part of the class. Why?

    • @nielshoogev1
      @nielshoogev1 ปีที่แล้ว

      @@ВладимирМакайда-м9т In organizations where much emphasis is placed on the number of lines of code one produces, using a language that requires a lot of boilerplate is a bonus. IDE's can generate such boilerplate, code analyzers can check that there are no errors, so in the end the developer can claim having done a lot of work, almost risk free.

    • @ВладимирМакайда-м9т
      @ВладимирМакайда-м9т ปีที่แล้ว

      @@nielshoogev1 Probably all the objections of the discussion are based on this.

  • @diligencehumility6971
    @diligencehumility6971 ปีที่แล้ว +1

    C# were perfect around C# 8 or 7. Now it's completely bloated. This is exactly how it became bloated. "We want to make programmers write less lines" so now you have weird symbols and strange syntax everywhere that's nobody understands, it's less readable, it's not helping anything really, yeah it took 1 sec less to write my class hurray, now it's difficult to understand what's going on. Please stop it.

    • @ivankovachev8835
      @ivankovachev8835 ปีที่แล้ว

      I absolutely agree, I'd say C# 9 and .NET Core 3.1/5 was just right for me. Now they have too much stuff, they break too much old stuff, and you have to relearn stuff, because now the syntax is different or they work differently.

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว

      I think for me it is about using the features when and where they make sense for you in your apps. Most of my constructors are just dependency injected in so this cleans them up for me for sure. Also don’t sure new features if they aren’t your cup of tea, no one is forcing you too. They are also all built and proposed in the open :) go give some feedback!

  • @gregdennis6094
    @gregdennis6094 ปีที่แล้ว

    I know it's demo code, but.... WHY DOES YOUR PERSON HAVE A PRINTNAME() METHOD?! And then.... WHY ARE YOU INJECTING A LOGGER INTO IT?! These dependencies are so wrong!

  • @fayazvar3948
    @fayazvar3948 ปีที่แล้ว

    If i have some logic in Constructor.

    • @JamesMontemagno
      @JamesMontemagno  ปีที่แล้ว +1

      Don’t use primary constructors if that is the case. As you saw it is great when getting rid of assignments, but if you want a bunch of logic (which I avoid at all costs) then just standard constructors

  • @Forshen
    @Forshen 11 หลายเดือนก่อน +2

    I find this kind of code disgusting. There is too much happening under the hood and you have to have more knowledge about the feature / flow of the code. Your default constructor gives us a scope and a 'main line' about the executing of the code and how it all connects together.

    • @bobweiram6321
      @bobweiram6321 9 หลายเดือนก่อน +1

      It's beyond disgusting! A primary constructor parameter can have the same identifier as a class member. Is it worth introducing a blatant language inconsistency for the sake of saving a few lines of code? It's a bad tradeoff.

    • @Forshen
      @Forshen 9 หลายเดือนก่อน +1

      @@bobweiram6321 totally agree, less code != clean code

    • @holger_p
      @holger_p 2 วันที่ผ่านมา

      The idea is: you don't need to know what's under the hood.

    • @Forshen
      @Forshen 2 วันที่ผ่านมา

      @@holger_p if you think that's a good thing... get more experience.

    • @holger_p
      @holger_p 2 วันที่ผ่านมา

      @@Forshen If you want to blame people, go somewhere else.
      I told you the idea, not that I like it or anything similiar. Programmers should be good in analysing texts.
      Syntactic sugar is most often hiding something.
      Old guys dislike to not use their knowledge.
      New guys like things work, without knowing why.

  • @iimv
    @iimv 6 หลายเดือนก่อน

    this is the definition of bs. Nothing new, just different.

  • @RusWatcher
    @RusWatcher ปีที่แล้ว +1

    it only makes the code harder to understand. everything is scattered around the class.