Why all your classes should be sealed by default in C#

Sdílet
Vložit
  • čas přidán 11. 09. 2022
  • 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 explain why you should be sealing all your C# classes by default. We will take a look at the functional aspect of the sealing feature and then take a look at the performance as well.
    Link to analyzer issue: github.com/dotnet/runtime/iss...
    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 • 372

  • @MHjort9
    @MHjort9 Před rokem +169

    These kinds of easy optimization tips is my favorite type of content from you Nick.
    Making the world a more informed place, 0.2239ns at a time

    • @davidparker5530
      @davidparker5530 Před rokem +9

      This doesn't make any sense 0.2239ns is essentially the time it takes to execute a single clock cycle on a 4Ghz processor. That's hardly enough time to even execute the return instruction. Aside from the suspicious benchmark numbers, all this optimization boils down to is removing the indirect call of looking up a virtual function address in the classes vtable and replacing it with a direct call instruction. At that point just make the method static / create a free function and you get the same effect.

    • @anderskehlet4196
      @anderskehlet4196 Před rokem +1

      @@davidparker5530 - we have instance members for a reason. Getting the performance of static without changing the code seems like a good deal.

    • @davidparker5530
      @davidparker5530 Před rokem +3

      @@anderskehlet4196 "performance" will be relative and YMMV. If you have a function that does some heavy computation, the overhead of a call vs indirect call won't matter at all (we're talking about a ns or two savings...). It makes no sense to just blindly seal all your classes for "performance". Take any real class that does something useful and seal it and measure how you get no real world performance benefit from it, this whole video is just a contrived example with a poor benchmarking setup.

    • @RiversJ
      @RiversJ Před 11 měsíci +2

      @davidparker5530 That's a bit short sighted in my opinion, obviously in the grand scheme of things one shouldn't chase tiny improvements, but the relative difference is key here, if you implement this in all hotpaths in the application the change is rather dramatic and you won't even need a benchmarker to see itz you can see it with your own wet eyes. There are lots of places where C# is applied and Is performance sensitive. Try what happens when you're iterating stays in the teens of thousands with sealed vs open, it's huge for very tiny effort. Just write one more word!

  • @stephaniewallace311
    @stephaniewallace311 Před rokem +122

    Praise from a random viewer: I’m very much a reader, and if I expect an article and land on a video, I’ve already hit the back button. Your videos are not only excellent enough to transcend my prejudices, but to provide some income with perks as well. Many thanks from an internet stranger for your fantastic work.

    • @mattshu
      @mattshu Před rokem +3

      I’m so the opposite and wish that could change lol (regarding the first part. love these videos)

  • @hichaeretaqua
    @hichaeretaqua Před rokem +20

    I solved this issue a long time ago by changing the class template in ReSharper/Rider to internal sealed. My goal was not to improve performance, but to not accidently exposing a API I don't indent to expose. It's nice to see that the performance is also benefiting from it.

  • @micmacha
    @micmacha Před rokem +6

    As a frequent C programmer, one of the things I appreciate about C# is the ability to throw an OOP concept or trope like garbage collection overboard. There's definitely a place for them, but if I'm doing something like DSP it can be a performance factor of over a thousand just to clean up after myself instead (unchecked, unsafe), and work with buffers directly. So, I appreciate the occasional "do we always need this" introspection from the C# team.

  • @Krilllind
    @Krilllind Před rokem +8

    In a comment I made on one of your previous videos, I mentioned the preferred "composition over inheritance" pattern and got so much pushback. Glad to see you mentioning this as well!

  • @cyex4311
    @cyex4311 Před rokem +4

    New coder here. What I took away was “sealing classes not meant for inheritance = better performance”.

  • @peymannaji
    @peymannaji Před rokem +1

    Absolutely love this video. Thanks a lot for this video.

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

    Thank you for this video. I enjoy videos about the performance and features of C#.
    By the way, I wanted to mention that in .NET 8 (I tested it on .NET 8.0.101), there are no significant changes in performance when running methods and changing arrays to spans. However, other cases still show the same performance differences. This means that it’s still important to seal your classes in .NET 8.

  • @saddamhossaindotnet
    @saddamhossaindotnet Před rokem

    Loved it. Thank for sharing!!!

  • @robertotumini395
    @robertotumini395 Před rokem

    Probably your best advice until now. Thanks!

  • @jimread2354
    @jimread2354 Před rokem

    Wow! I had no idea the performance difference that existed between. I'm really glad I watched this!

  • @weekendrobot
    @weekendrobot Před rokem +8

    I hate this advice because I have managed to fix so many broken framework and library classes over the years by using inheritance. And entire avenue of bug fixing possibilities are quickly disappearing. These classes are not intended to be inherited and extended and these fixes are brittle but at least they're possible. I'd rather be able to work around an issue today and fix my workaround tomorrow than just be stuck.

    • @TehGM
      @TehGM Před 3 dny

      I tend to say: a good quality of a library developer is to be aware that you might not think of what is needed NOW, but end users might come up with different ideas.
      I like this advice for non-library projects. It's like free gains, and you can always change it in your project. But a good library author will allow users to extend it however they see fit.

  • @briansandberg8229
    @briansandberg8229 Před rokem +12

    You'd think the runtime could handle this. The jitter knows if any classes inherit from this one, and if additional assemblies are loaded at runtime then the affected code could be re-jitted.

    • @ZintomV1
      @ZintomV1 Před 8 měsíci +1

      It probably wouldn't be a good idea to run this at JIT due to the performance impact of that analysis. Much better to evaluate at compile-time and seal all classes without members that inherit them.

    • @smathlax
      @smathlax Před 23 dny

      ​@@ZintomV1 You can't evaluate that at compile time because you don't know if an external assembly is inheriting from that class.

  • @vdrasutis
    @vdrasutis Před rokem

    Nice and short as always, great video

  • @rodionsabbath9722
    @rodionsabbath9722 Před rokem

    thanks Nick, great information.

  • @thomasschroter3802
    @thomasschroter3802 Před rokem +1

    Yeah! Since I played along with Kotlin some years ago, I got used to sealing all my classes in c#.
    It is not only a question of performance but, first of all, good an robust design of my code.

  • @eduardpopescu9109
    @eduardpopescu9109 Před rokem +2

    I totally agree with this, and I was thinking maybe change the New Class template that Visual Studio uses to create sealed classes?

  • @MrMatthewLayton
    @MrMatthewLayton Před rokem +3

    Totally agree. Having been a Kotlin developer for the past few years, I've learned to appreciate sealed (or final) by default, and now I apply it as a matter of habit to C# projects. Whilst .NET doesn't implement sealed by default for classes, it does for structs, which is why you can't extend them. If you look at the IL for a struct, you'll notice they're marked sealed, and as .NET has no mechanism to 'unseal' a type, you simply can't extend them.
    The other thing that would be nice is if C# had a language-level equivalent of Kotlin's 'sealed' (which is not the same as C#'s sealed), where you can create an abstraction that is only intended to be implemented within the same assembly. You can achieve this however by using internal constructors, so that it's not possible for extension beyond the current assembly.

  • @Havie
    @Havie Před rokem

    Always wondered about this , thanks!

  • @davemasters
    @davemasters Před rokem

    Well you learn something new everyday! Thanks Nick

  • @SilasPeters
    @SilasPeters Před rokem +6

    I love the little Hello World eastereggs! Such a personal touch

  • @AbhinavKulshreshtha
    @AbhinavKulshreshtha Před rokem +8

    As a kotlin dev, I really like the sealed nature of language, But coming from Java/C# background, I used to have a mindset that classes should allow for inheritance. I used to think that just encapsulation means a lot of objects running around in memory. It took me a while, a good mentor, and a lot of performance benchmarks to realize the runtime benefits far exceeds the memory overhead, and also that a badly designed inheritance will actually consume more memory than encapsulating multiple objects.
    Great video as always. I really love all the benchmarks numbers that you show to validate your tips.

    • @fr3ddyfr3sh
      @fr3ddyfr3sh Před rokem +8

      Badly designed inheritance has a ton of disadvantages, strong coupling, hard to understand, hard to maintain.
      Sometimes impossible to refactor, because 20 different inherited classes are strongly coupled, and minor changes, can lead to subtle (but devastating) behaviour changes.
      In 90% of the cases:
      Prefer composition over inheritance

    • @ExpensivePizza
      @ExpensivePizza Před rokem +4

      @@fr3ddyfr3sh Absolutely agree that you should prefer composition over inheritance in 90% of cases. The only problem with this mantra is that most people don't understand the other 10% of cases.

  • @joevm3
    @joevm3 Před rokem

    Thank you for your videos. This is very useful for me.

  • @Andrei-gt7pw
    @Andrei-gt7pw Před rokem +9

    There should be a setting which instructs the compiler to make all classes in a project sealed if they are not inherited. Could be usefull when you don't plan to roll out your code as a reusable library, which is most often the case.

    • @thebigstach919
      @thebigstach919 Před rokem +1

      Wish someone from development team could say something about this idea.

    • @julkiewicz
      @julkiewicz Před rokem

      Probably easier to write a simple post-processing tool in something like Mono.Cecil to do that. You have to consider that in C# it is possible to load DLLs dynamically. Something might get extended in a different compilation unit, the existing tools haven't been designed for this case. But it's maybe a 100 lines in Mono.Cecil to make such a change.

    • @TheJochance
      @TheJochance Před rokem

      @@julkiewicz Yup. Late binding very likely goes right to the heart of why there is a performance benefit to doing this. Apparently someone else has tested this and says virtual is the kicker, sealed/unsealed otherwise won't matter.

  • @silentdebugger
    @silentdebugger Před rokem +7

    I jumped in hoping for a great performance boost after sealing ~1800 classes in my project. Perf increased by 0.3% overall. So kind of a mixed bag... Ah well, thanks for covering the fundamentals

    • @PhilippLenssen
      @PhilippLenssen Před rokem +4

      Wouldn't the compiler optimization already know which classes aren't ever inherited in the project, thus quasi-seal them for the build?

  • @alxmajor166
    @alxmajor166 Před 8 měsíci

    I agree. The largest accurately measured specimen of the elephant seal was a bull which weighed at least 4 tonnes.

  • @anm3037
    @anm3037 Před rokem

    Thank you Nick. You just made me christmas

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

    I like the numeric values you use as examples.

  • @adiazwise
    @adiazwise Před rokem

    Excellent article Nick thanks , I wonder if this apply for records too.

  • @debtpeon
    @debtpeon Před rokem +55

    This is not a "design flaw". This is a historical artifact of object oriented languages where classes are designed to be inherited by default. This also permit classes in libraries to be extended. Clearly over the years there's been a move away from object orientation with better methodologies of extending features. C# was based on Java and other OO languages at the time.

    • @rauberhotzenplotz7722
      @rauberhotzenplotz7722 Před rokem +16

      Hmm, inheritable by default, but methods not virtual by default.

    • @matthewwood4756
      @matthewwood4756 Před rokem +4

      @@rauberhotzenplotz7722 - “encapsulation” is still one the 3 benefits of OO though….that’s one of the points of inheriting non-virtual methods.

    • @timseguine2
      @timseguine2 Před rokem +3

      @@matthewwood4756 You can accomplish pretty much anything that is achievable with inheritance with composition instead, and it is usually more flexible, cleaner, and separates concerns better without sacrificing encapsulation.

    • @matthewwood4756
      @matthewwood4756 Před rokem +1

      @@timseguine2 - I’m not necessarily disagreeing with you, but using true OO principles of multiple inheritance, the same can easily be achieved that more readily/accurately “models” real-world problems/designs/solutions. “Composition” is the answer/pattern that has naturally evolved due the mainstream implementation/acceptance of single-inheritance languages/compilers.

    • @timseguine2
      @timseguine2 Před rokem +3

      ​@@matthewwood4756 No. Classical OO often confuses the object hierarchies' isA relationship with the isA relationship of the thing they are modelling. These aren't in general the same relationship from a mathematical standpoint, so it doesn't make sense to model them like they are the same thing.
      The argument against inheritance comes historically from the Liskov Subsitution Principle and has absolutely nothing to do with single versus mutiple inheritance languages.
      Or put more charitably, you are reversing cause and effect
      Yes in languages with single inheritance there is additional motivation to favor composition over inheritance, but that was partially the motivation for them deciding to force single inheritance in the first place.

  • @timseguine2
    @timseguine2 Před rokem +1

    I usually always avoid implementation inheritance. So I have been doing this for a while.
    And even the general rule is: either design for implementation inheritance or forbid it. I usually design for interface inheritance, so yes, of course I seal my classes since I am not designing them for implementation inheritance.

  • @JosifovGjorgi
    @JosifovGjorgi Před rokem +3

    Like every advice from every "guru", sealed classes in every language are usable in small number of use-cases.
    If you can't inherit a class then every framework that is depending on proxy design pattern (for creating "sugar" classes) will fail and the list of frameworks is very large RestControllers, ORMs, DI etc.
    And why those framework will fail ?
    Because all of them depend on proxy design pattern, which can be implemented in three ways
    1. as a pair (interface and class) or
    2. as inheritance of the class annotated with metainformation.
    3. provide factory methods for every sealed class, that will be use by the frameworks (mostly use in DI)
    If you are using sealed then you must 1 or 3
    This means every seal class needs to have "dummy" interface in order for the framework A to create "the sugar" sealed class or factory method
    Congratulations, instead of one "sugar" class A, know you have sealed one "sugar" class A + dummy interface IA / factory method and your code base is now twice as big.
    Don't get me started on ORMs, there is a high change that the amount of SQL generation will be double or you will wonder why ORM always generates insert statements.
    But this is just the software developer perspective
    From library POV - in order to fight sealed word, the libraries have to provide compiler hooks and now instead of Microsoft or your fav language company you have to wait 3-rd party company to fix your compiler bugs
    Classes shouldn't be sealed by default, because they are almost always useless

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Everything you said can be done with interfaces and composition in C# :)

    • @JosifovGjorgi
      @JosifovGjorgi Před rokem

      @@nickchapsas yes
      However,
      if project with unsealed classes has 1000 classes
      then project with sealed classes will be at least 2000 classes
      And that is the price to pay for using sealed keyword by default

  • @joseluiseiguren7827
    @joseluiseiguren7827 Před rokem

    Awesome man!!!

  • @kuljok
    @kuljok Před rokem +8

    Hey Nick
    I'd like to say thanks for your video and I have a question. The performance sag in your example could be a consequence of the virtual method table (not just because of "sealed" class). If you try to remove the "virtual" word you will see the other results.
    It does not negate the fact that type casting and some other operations are faster with sealed classes, but I think the "sealed" is not something that always makes performance better.

    • @zer0K3lvin
      @zer0K3lvin Před rokem +5

      Actually was wondering about that and tested it ... if it's not virtual its just the same speed ... so sealed/unsealed has no impact on none virtual methods.

    • @0shii
      @0shii Před rokem

      @@zer0K3lvin Thanks for testing that, I was wondering as well!

  • @m5s10
    @m5s10 Před rokem +7

    Hey Nick, thanks for the great video. I have two questions. 1. Is the performance difference only in .net 7, or is it in older veresions as well (.net 6, 5, .net core, .net framework)? 2. Usually there's no such thing as free lunch. In the video you displayed making class sealed (if possible) as an absolute positive, with no negatives. Are there some known drawbacks to doing it? Thanks :)

    • @nickchapsas
      @nickchapsas  Před rokem +9

      1, Yes i applied to previous versions as well. 2. The "negative" is that you can't inherit from it anymore but if you were never planning to do so then it's just positive.

    • @m5s10
      @m5s10 Před rokem +1

      ​@@nickchapsas Thanks for the quick reply. Most of the classes are not inherited anyway, so this might give us some performance gains. I'll give it a shot.

    • @alexander4468
      @alexander4468 Před rokem

      @@nickchapsas Could you please share your opinion about how to test such sealed classes? could it be measured as "negative" point of this approach? Because I can see a problem with some legacy or some projects with non-structured test strategy where such "sealed by default" might lead to issues when we try to mock them or create a stub for such classes (if there was no adaptors which would allow to mock them instead of the classes directly). Thanks!

    • @yunsha9986
      @yunsha9986 Před rokem

      @@nickchapsas I second this Nick, could you show a fiddle of how you unit test those sealed classes?

  • @katjejoek
    @katjejoek Před rokem +2

    Hi Nick, thanks! I didn’t expect sealed to make such a difference.
    Any chance of the analyzer being released to older versions than .net core 7?

    • @MoireFly
      @MoireFly Před rokem

      Analyzers depend on sdk version. You can use the new sdk to target older versions just fine. Worst case you could multitarget, e.g. for nullability, but that won't be necessary here.

  • @volodyasenchak1907
    @volodyasenchak1907 Před rokem +6

    You noticed in this video that inheritance now is considered an antipattern.
    I tried to find some nice examples of how we can replace inheritance with composition, but I couldn't find some nice examples.
    Could you please make a video on how we can refactor code with inheritance to the composition?)

    • @nickchapsas
      @nickchapsas  Před rokem +12

      I will make a video on the topic. It's not as simple are replacing class extension with interface implementation. It goes deeper than that

  • @luca-dallavalle
    @luca-dallavalle Před rokem

    Great video.

  • @obiwanjacobi
    @obiwanjacobi Před rokem +4

    Change your class template in your IDE to include sealed by default (and make them internal while you're at it).

    • @wesplybon9510
      @wesplybon9510 Před rokem +1

      Just keep an eye out when you do updates. I've made template changes in VS before and updates will wipe them out.

  • @ristopaasivirta9770
    @ristopaasivirta9770 Před rokem +42

    I'm curious if this has any effect after the code is converted using IL2CPP as is often the case when making final builds on Unity.
    Really interesting and awesome never the less!

    • @SunSailor
      @SunSailor Před rokem +3

      I even wonder, if this is the case for Mono in the first place.

    • @piotrzdanowski5873
      @piotrzdanowski5873 Před rokem +6

      tactical dot in case someone will be less lazy than me and tests it: .

    • @Xankill3r
      @Xankill3r Před rokem +11

      Basically no difference in 2021 LTS as the .Net versions supported are Standard 2.1 and .Net 4.0. Neither of those have the specific optimization being talked here in the IL (using direct call instead of callvirt).

    • @SunSailor
      @SunSailor Před rokem +2

      @@Xankill3r Thank you for pointing out! Makes sense.

    • @ristopaasivirta9770
      @ristopaasivirta9770 Před rokem +2

      @@Xankill3r Thanks!

  • @shayvt
    @shayvt Před rokem +4

    Can you do a video about the inheritance anti-pattern?

  • @klightspeed
    @klightspeed Před rokem

    The performance improvement on the methods suggests that they are being inlined, and the performance improvements on the is / as would be because it can directly check the type instead of checking if the type being tested is assignable from the type of the value.

  • @one.pouria786
    @one.pouria786 Před rokem +6

    I think if ide(s) like Rider and Visual Studio add this feature (Adding sealed keyword in snippet code of Creates a class declaration)
    It will be reasonable and more practical.

    • @EmptyGlass99
      @EmptyGlass99 Před rokem +1

      Do you know if there is a setting in VS? When I create a new class, it defaults to internal.

    • @nickchapsas
      @nickchapsas  Před rokem +9

      With the new analyzer you can make rider remind you and I'm pretty sure they will be adding a refactoring too

  • @jctrevis
    @jctrevis Před rokem

    AWESOME content!
    Do this rule of sealed classes also work for the old .NET Framework? Is there a gain in performance there as well?

    • @nickchapsas
      @nickchapsas  Před rokem

      Yes the performance benefits have been there since forever

  • @yossisternlicht21
    @yossisternlicht21 Před rokem

    Great video, as usual. One point I noticed in your tutorial (and Stevens issue) is that both the sealed class and the open class are themselves inheriting from a base class. Would the same hold true if both of these classes were not explicitly inheriting another class?

  • @andriisnihyr6497
    @andriisnihyr6497 Před rokem

    Great video, thank you! I expect there would be a lot of comments from people who oppose sealing everything :D

  • @jamesterwilliger3176
    @jamesterwilliger3176 Před rokem

    I couldn't agree more with this video. I check for this in code reviews and insist that things be sealed unless explicitly needed otherwise.

  • @LuigiTrabacchin
    @LuigiTrabacchin Před rokem +5

    I Think that with the new feature of C# "Extension everything" this could be adopted in very fast way

  • @slowjocrow6451
    @slowjocrow6451 Před 7 měsíci

    Any good talks/examples on "composition over inheritance"?

  • @Chainerlt
    @Chainerlt Před rokem +5

    I've been using c# as my main horse for over a decade, even wrote transpilers to IL and still learned something new today, thanks!

  • @AlFasGD
    @AlFasGD Před rokem +3

    6:10 it's easy to fall into a pit of misconception, so I'll drop my thoughts there
    Notice those ZeroMeasurement warnings down there, those say that method duration is too small to be taken into account, often times because the method is inlined and its execution takes virtually the same time as calling an empty method, meaning it's "the fastest you can get" when comparing vs calling a method. So it's not actually "38x" faster or "1000x" faster, it's "the fastest you can achieve".

    • @nickchapsas
      @nickchapsas  Před rokem

      I had run to run variance between the executions so in some cases it was ZeroMeasurement and in some it wasn't so I left that comment out

    • @AlFasGD
      @AlFasGD Před rokem +2

      This is probably an effect of the methods not being correctly aligned for an ideal implicit inlining scenario, but either way if you do notice a zero measurement warning, you should assume that it's happening sometimes.
      Remember that given how inlining isn't perfect, were that same zero measurement warning to appear every single time, the performance could easily not be as high in as many as half the cases in a real world scenario. This is microbenchmarking and sets up and ideal scenario to juice out the maximum performance, isolating as many external variables as possible.
      TL;DR always worth noting that *even once* you get a zero measurement warning.

    • @gnack420
      @gnack420 Před rokem

      @@AlFasGD obviously you're not wrong, and the information you've posted is super interesting to me so thank you! But I think the benchmarks here are just to show clearly that there IS a performance gain for zero cost, the video is explaining why sealed should be default and demonstrating that there is ANY performance improvement is a good enough argument to support that.

    • @AlFasGD
      @AlFasGD Před rokem

      @@gnack420 I agree but I also believe that it's generally good to perform a general fact check

  • @madcroc111
    @madcroc111 Před rokem +10

    Sealed can be very annoying too. Like when you want to modify third parties code. Extend it and modify one function you want. With composition you cannot input it into functions that take the original class, only that take an interface, so you have to copy all the functions too that take or depend on original class.

    • @ashlar64
      @ashlar64 Před rokem +1

      Exactly....it's happened to me a few times.

    • @MoireFly
      @MoireFly Před rokem +1

      That's a feature, not a bug. You're going to be doing that so so much more rarely than actually working on a normal class. Allowing instance means that normal code now needs to maintain invariants even in the face of fairly hard to predict code replacement. Your subclass needs to be tightly coupled with the base class, and needs to understand what the actual class internal api is, because if the base class ever changes anything, you're likely to encounter all those hidden assumption on a bug report.
      The effort of rarely copying a few method declarations is so much smaller than the effort of dealing with unnecessarily flexible code, especially if anyone was ever so unwise as to abuse that flexibility.
      Inheritance as a form of method interception is a recipe for unmaintainable spaghetti code.

  • @mindstyler
    @mindstyler Před rokem +3

    We really need a way to specify different c# 'versions' so features can be changed retroactively without having to worry about backwards compatibility. Any new project will use the most up to date recommended version and if an older project is upgraded, they can change individual settings to reenable compatibility modes. I think that would be awesome.

    • @mindstyler
      @mindstyler Před rokem

      @@MiningForPies no this is not what i mean here at all.
      i mean: instead of classes being implicitly open by default, and you have to seal them with the sealed keyword, in the recommended version classes would be sealed by default and there would not be a sealed keyword, but rather an 'open' keyword.
      the same applies to other features, for example _ in lambda is a discard, even in single argument lambdas (which is not currently the case because of backwards compatibility concerns by the .net team)
      and there's a whole list more of similar features.

    • @mindstyler
      @mindstyler Před rokem

      there are already programming languages that have a 'version' model like this. nick has even mentioned it in a video about it a few months back. (though i cannot quite remember which one)

    • @gnack420
      @gnack420 Před rokem

      You can specify the language version in your .csproj files.

    • @mindstyler
      @mindstyler Před rokem +1

      @@gnack420 are you people even reading what i am asking for? cause apparently you dont.

    • @a11d
      @a11d Před rokem

      Wtf are these replies people don't read 😅
      I commented exactly this and saw this comment. Do you know what the stance of the c# team on this is? It should have been discussed at least right?

  • @Skurdt
    @Skurdt Před rokem

    The performance benefits also seem to apply (not fully though) for an "open" class that uses sealed override methods. (public sealed override ExampleVoidMethod() { })

    • @nickchapsas
      @nickchapsas  Před rokem

      Only on the method invocation itself. Having the class sealed applies them to everything for instantiation, to type checks to method calls etc

  • @felipeklafke
    @felipeklafke Před rokem +1

    obrigado. agora que você postou as pessoas devem me ouvir mais 🤣🤣🤣

  • @sanyanders
    @sanyanders Před rokem +1

    I think right now it's needed to be included into linters warnings by default like "The class %ClassName% is not inherited anywhere and can be made sealed". Is there any suggestion for this on JetBrains YouTrack?

  • @MagnusBertilsson
    @MagnusBertilsson Před rokem +27

    This may be great in theory, but in practice when trying to test either legacy systems or library without a good testing strategy. Sealed classes have stopped me from writing unit test many times. Especially when you want to implement tests without changing legacy code.
    For new systems it might be more applicable, but they will be legacy system one day. So how do you want to leave the code for future developers.

    • @gnack420
      @gnack420 Před rokem +10

      This is a design flaw in your code. Third party services/libraries should be abstracted using an adaptor that conforms to an interface that you've written. You can then trivially mock the adaptors in your unit tests. There's no need for those third party libraries to be unsealed if you are properly abstracting your dependencies. You should also avoid injecting concrete types as dependencies whenever you can.

    • @MagnusBertilsson
      @MagnusBertilsson Před rokem +7

      @@gnack420 Well that is also a question about theory and practice. Yes I know all about abstracting dependencies. I have 10 years experience with looking at old code that either only is the layers of abstractions or looking at code that has no abstractions. And the one thing that made me utter profanities more then others is sealed classes. When trying to test.
      And it’s a lot easier to end to end test code without infrastructure when third party libraries do not use sealed on their classes. Yes I can write a lot of unit tests with my abstractions but if I send the wrong property in the wrong argument in my implementation. The only thing the fast code will produce is more problems for me to clean up in production if QA don’t catch it.

    • @Marfig
      @Marfig Před rokem +5

      This is correct Magnus. Unit testing is one of the shortcomings of sealed classes. And being told I have to extend my object model to support unit testing because I sealed all my classes, flies in the face of everything we learned about object data models, and the quest for simplicity and extensibility. I admit there may be outlier use cases in which sealing all my leaf classes is a necessity or a sound design choice. But for the vast majority of object models in the world, even considering C# little semantics flaws and idiosyncracies, sealing a class should be a structural decision about the object model. Not the result of an arbitrary generalization to gain infinitesimal performance gains on an application that has no performance issues in the first place, or where those performance issues are understood to live somewhere else in the code. This wasn't one of Nick's best days.

    • @Marfig
      @Marfig Před rokem +3

      Three examples in which I would want to seal my class:
      (1) I'm writing a class with value-type semantics.
      (2) I'm writing a code generator for an engine or interpreter which relies on specific types being consumed.
      (3) I'm writing a utility math class composed entirely of truisms. (On this special case, extending behavior is best achieved through composition).
      All in all, Microsoft advice in the sealed keyword documentation page still stands. In short, do it only if it makes sense. Avoid it otherwise.

    • @FudgeYeahLinusLAN
      @FudgeYeahLinusLAN Před rokem

      @@MagnusBertilsson I don't understand. When unit testing a class, you're supposed to test the methods of that class, no? Ergo, instantiate an object of the class, call its various methods with various parameter values, analyze the results. Sealed or no sealed class makes no difference, legacy or brand new class makes no difference.

  • @Andruuid
    @Andruuid Před rokem +6

    The Microsoft Documentation from April 2022 says: DO NOT seal classes without having a good reason to do so.
    "Sealing a class because you cannot think of an extensibility scenario is not a good reason. Framework users like to inherit from classes for various non-obvious reasons, like adding convenience members. See Unsealed Classes for examples of non-obvious reasons users want to inherit from a type. ..."
    Also Mocking is a Problem.... thoughts?

    • @nickchapsas
      @nickchapsas  Před rokem

      I clearly disagree with that as well as many developers in the C# and .NET team. You can clearly see that MS themselves don't follow that rule. Docs advice is designed to be beginner friendly. There are tons of advice in there I disagree with.

    • @Andruuid
      @Andruuid Před rokem

      @@nickchapsas Ok Thanks!, I actually think the same

    • @paulkoopmans4620
      @paulkoopmans4620 Před rokem

      You do have an option to 'extend' sealed classes. You can do it with extension methods!
      The same article you are referring to though also ends with: "Portions (C) 2005, 2009 Microsoft Corporation. All rights reserved." and comes out of a book "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition", Published Oct 22, 2008.
      We are back to that since 2000 to 2010.... the developer landscape has changed significantly and this is just one of many 'viewpoints' that have changed/shifted.
      There is definitely a big issues too with not sealing your types. Because it implicitly means that you as a developer, especially if you write a library, would have to put a lot of defensive code in to ensure that outside users implement the types different or wrong.
      Personally I also favour using extension methods even on types that are inheritable if possible of course. If I just need to add a helper, like addind an AddRange() or some display or factory method or something. Rather then to deal with the inheritance and having to implement then everything the thing needs to have.
      I always have to think back to one time I had to do it, having to add a helper to a certain type. I had to do it by inheritance but due to other bad design practices by the api designer, I was forced to implement 30 other methods.

    • @bass-tones
      @bass-tones Před rokem +1

      @@paulkoopmans4620 Extension methods currently have a ton of limitations though. For example, you cannot do something as basic as adding a property to a class using extension methods.
      Yes perhaps this is eventually coming but it’s probably at least 2 years out from being included in the language.

    • @paulkoopmans4620
      @paulkoopmans4620 Před rokem

      @@bass-tones Yes I understand that extension methods are only able to do anything with the object by using its public interface. The name 'extension method' is a bit deceiving and I realize I am actually not 'extending'. The class does not change by creating extension methods.
      A sealed class though, which this topic is all about, will never be able to get any extension whatsoever, but at least you can add some helpers like maybe an AddRange() method that calls the single Add() method provided by the library. Or maybe a Search() or ToEnumerable().
      This is also still where encapsulation might also help you out, IF and ONLY IF the designer of a library actually has done it properly and depends on interfaces.
      If you ever wrote an external facing api (not webapi, but as a library I mean) then you know why you would try to make pretty much everything internal and the stuff that is public you very likely want to seal. The actual classes, from a library perspective, that NEED TO BE extendible by inheritance as the only option in order to be useful to the user, is probably near zero.
      Sealing your classes and guarantee yourself that your classes do 'exactly' what you expect them to do far outweighs the pain, risk and cumbersomeness that you would have to add if you leave your classes open for inheritance and your code consuming then would have to have all kinds of defensive code and checks in them.

  • @root317
    @root317 Před rokem +4

    Ok this will be interesting. I have never used sealed before.

    • @root317
      @root317 Před rokem +2

      Ok this was totally worth it. Learned one more thing today. Thanks for the vid Nick, great job as always :)

  • @wknight8111
    @wknight8111 Před 9 měsíci

    I've been making my classes sealed by default for years now. I don't do it for performance reasons (though every little bit helps!), I do it because I don't like to use inheritance when I don't have to. "Prefer delegation over inheritance", etc. I only wish VS made it easier to change the default class template, so I could make those changes more quickly and easily.

  • @manmohanmundhraa3087
    @manmohanmundhraa3087 Před rokem

    Eye opening video. Is same is true for sealed method ?

  • @neociber24
    @neociber24 Před rokem +5

    I tried that, but notice you can't seal some entities when using dotnet EF because they use a Proxy for the DB

    • @fr3ddyfr3sh
      @fr3ddyfr3sh Před rokem

      Definitely, that’s how EF and also NSubstitute work.
      But the latter will most likely be used on interfaces

    • @bartdeboer
      @bartdeboer Před rokem +1

      True but those are not the type of calls that you expect in a inner loop as they are io bound , so nanosecond improvements won't matter anyway.

    • @FudgeYeahLinusLAN
      @FudgeYeahLinusLAN Před rokem

      Yet another reason to not use EF in my book. I'm an EF survivor and have been EF free since 2010. :)

  • @yossiyaari3760
    @yossiyaari3760 Před rokem

    I wonder if there is a similar performance hit in JAVA.
    I have been dealing with Azure clients in JAVA that are sealed (final), and they are a pain to mock. I guess this discussion has motivated the MSFT team to mark these classes as final.
    I'm pretty sure that C# has easy ways to mock sealed classes, but JAVA doesn't seem to have them. I assume that the wrappers I wrote to overcome this will probably consume any overhead advantage that making the classes final achieved.

    • @jongeduard
      @jongeduard Před rokem +1

      See my own reply about virtual methods. I don't know that much about Java APIs in practice and how they have their code written, but there is an extra issue in Java that methods are virtual by default, which just like inheritable classes, require runtime checks along the inheritance tree. Methods should have been final by default, and virtual just as an option.

  • @EduardoAG
    @EduardoAG Před rokem

    Is there a a video about inheritance vs composition in classes in C#?

  • @levmatta
    @levmatta Před rokem +2

    Before watching: I Absolutely hate SEALED, cannot estimate how many hours waisted copying disassembled classes and still failing to customize what I needed.

  • @TheDjblane
    @TheDjblane Před rokem +1

    @Nick Chapsas what about public class XXXController : ControllerBase in web api?

  • @TheAproeX
    @TheAproeX Před rokem +5

    Is the difference only measurable in newer versions of .NET? Or will it be worth sealing all classes in .NET Core 3.1 as well?

    • @nickchapsas
      @nickchapsas  Před rokem +3

      They apply to .NET Core 3.1 too

    • @protox4
      @protox4 Před rokem

      Even older than that, full framework can take advantage of converting virtual calls on a sealed class to direct calls.

    • @yuriihonchar9336
      @yuriihonchar9336 Před rokem

      ​@@protox4 not really. The results on Full framework(.NET 4.8) show almost no difference between sealed and open classes

  • @nathanieljennings3311

    Rider has an inspection severity setting for this outside of .NET 7 under Settings / Inspecting Settings / Inspection Severity / C# / Class can be made sealed (non-inheritable)

  • @DavidRosensteel
    @DavidRosensteel Před rokem

    I was a little skeptical. Inheritance is a big feature to make a general statement about throwing it away. But interfaces exist, so having most classes sealed and interfaces available could give the performance boost of sealed while allowing for people to make their own API compatible classes. The main concern is that if something is missed and there isn't an interface or some other way to customize that part of the API and the relevant class is sealed then some dev somewhere is gonna break out reflection and do some sketchy hacks to get around it.

  • @yanpitangui
    @yanpitangui Před rokem

    Hi, Nick!
    Is it also useful to add to records?

    • @nickchapsas
      @nickchapsas  Před rokem +1

      Ofc. Records are just classes with some fancy hidden methods

  • @matthewdee6023
    @matthewdee6023 Před rokem +1

    So I had a look as to WHY, and it's mainly because a call to a VLT can be being turned into a direct call by the compiler, which makes sense (still not idea why the 'is' and 'as' operators run faster though) [edit]Same idea, the runtime doesn't need to walk the inheritance hierarchy.[/edit]
    I suspect that this will have less of an impact if you have a deep inheritance tree with all of the leaf classes marked as sealed, because any method that at runtime can accept the base class will still have to do a lookup. That said, if people stick to composition > inheritance that shouldn't be an issue ;-)

    • @TheKevinKaimon
      @TheKevinKaimon Před rokem

      Interesting! Where could I find more info on the why?

    • @matthewdee6023
      @matthewdee6023 Před rokem

      @@TheKevinKaimon It''s in the linked github issue :)

    • @ArrovsSpele
      @ArrovsSpele Před rokem

      Does compiler really can turn overriden and hidden functions with direct calls with ease? Or more advanced inheritance based trees are still at tables? I know that sealed in real life barely makes performace impact.

  • @jamesmussett
    @jamesmussett Před rokem +22

    Ive been making everything sealed for a while now but it is a chore to remember, especially for juniors. I think they should add an unsealed keyword anyway, that way they could have warnings on public types that don’t specify it explicitly.

    • @peryvindhavelsrud590
      @peryvindhavelsrud590 Před rokem +8

      Why not just reuse the existing virtual keyword and a project setting to default to sealed classes?

    • @1eyewonder27
      @1eyewonder27 Před rokem +3

      You could always create a class template or edit the default visual studio class template as an alternative if that is something you think wouldn't harm your team's code

    • @bluesillybeard
      @bluesillybeard Před rokem +3

      I agree, similar to how the public and private keywords work - you don't actually NEED both to write valid code, it's just good practice to specify weather something is public/private rather than leaving it up to a default value.

    • @queenstownswords
      @queenstownswords Před rokem +1

      I suspect if we make sealed a default, a lot of legacy code would break, yes? A code analyzer is the best way forward.

    • @peryvindhavelsrud590
      @peryvindhavelsrud590 Před rokem

      @@bluesillybeard It could be done in the same manner as nullable support was added to the project files. Legacy code could omit the setting and would work as previously to avoid breaking changes.

  • @chrismitchell9936
    @chrismitchell9936 Před rokem

    Hey Nick, I love this video and agree in 'general', but I see one glaring side affect: Mocking...when a class is sealed, I can't mock it. I can extract an interface, inherit, and then so long as I'm careful to ALWAYS use interfaces, all is well again (and in general, I use a lot of dependency injection and use interfaces, etc.) I worry though that the framework may not allow that...and being able to mock things is quite important...thoughts?

    • @nickchapsas
      @nickchapsas  Před rokem

      You’re not mocking classes you are mocking interfaces and abstract classes which can’t be sealed

  • @jongeduard
    @jongeduard Před rokem

    It all reminds me of a thing that the C# designers did right: methods are non-virtual by default. Java is in fact worse, you need to explicitly make your methods final. I have learned earlier that virtual methods are slow, because they require the runtime to perform checks along the inheritance tree all the time.
    But to be honest, I was not aware of such a thing to be te same on the level of entire classes. But it is a logical thing, all for the same reasons.
    I think of course we can all criticize this, but the idea behind those languages started with inheritance in mind as a general feature. Mindsets where very different in the past.
    The idea of gaining the far best performance like native code was already given up anyway I guess. Flexibility is what counted.

  • @MikeFrench
    @MikeFrench Před rokem

    Question I always asked is why the tooling, examples, compiler, whatever don’t do this by default?

  • @sigma_z
    @sigma_z Před rokem +2

    I've been sealing all my classes since forever. I'm happy this performance gain and lock down of inheritance is becoming more mainstream now. Thank you Nick

  • @volodymyrdombrovskyi8530
    @volodymyrdombrovskyi8530 Před 9 měsíci

    Apart from performance and clarity reasons, sealing the class which implements IDisposable saves you from not implementing dispose pattern

  • @modernkennnern
    @modernkennnern Před rokem +1

    I feel like many things, like Sealed being the default, could be changed, similar to NRT(Nullable Reference Types) - by adding a setting in the .csproj file.
    true
    true // This is currently not even a feature, but it hopefully will come soon.. and then potentially add a wrapper tag:
    2022 // This would then set all the default values (like NRT to enabled, both of the preceding values to true, and so on..)
    C# is an aging language and has a lot of flawed design decisions. I feel like, at some point, this needs some way of being addressed. Why do we, in 2022, have to live with poor design decisions made in early 2000s when we don't run _any_ code from that era?

    • @modernkennnern
      @modernkennnern Před rokem

      That said, Roslyn Analyzers are a great alternative to fixing the flaws. It keeps the flaws in, but makes it impossible to use them

    • @paulkoopmans4620
      @paulkoopmans4620 Před rokem

      you personally might not. But I know for a fact that the companies I have worked in since 2005 all are still alive.
      There is a fair chance that some of the original code is still there and running.

    • @modernkennnern
      @modernkennnern Před rokem

      ​@@paulkoopmans4620 They could still easily interoperate - It would still compile to the same lowered code.
      It is however a definitive problem with the consistency of the code across multiple projects, but I'd argue that's also an issue with NRT

    • @paulkoopmans4620
      @paulkoopmans4620 Před rokem

      @@modernkennnern I was just commenting on your claim that in 2022 there is no code from that era running anymore. :)
      Again given that the companies that I wrote .net 1.0 code for, in the 2000's are still around, I do want to believe there is still old code bases around.
      Now this particular 'flaw' of not sealing by default is even prevalent for code created last month.
      And I agree is a problem and that it is hard to break the cycle.
      I see what you are trying to say with comparing it to NRT. Yes; they are solved the same way. But also both of these suffer from the same problem. If you have some old library code sitting somewhere in your massive code base and you never get to address it, it still needs to successfully compile today. Therefore the compiler has to generate instructions that give the same behaviour today as it did 20 years ago. Which is why both NRT and this one will just generate warnings but will compile regardless.
      The reason why such a flag in a project file could not work is because for some new parts you finally want to start with classes that are sealed by default but this dark grey area of your massive project should not generate a sealed class, and unfortunately both of the lines are identical and the compiler could not tell which one to generate as which type. I appreciate that for a net new project and/or solution it could. But the having the warning and your IDE treating it as such is frankly the same experience.

  • @erikaknop6089
    @erikaknop6089 Před rokem

    Thank you. It really works 

  • @tobyjacobs1310
    @tobyjacobs1310 Před rokem

    Does this also work for interface access of sealed classes at all, or do you have to know the underlying type?

    • @pbolduc
      @pbolduc Před rokem

      I was going to ask the same question. If we are using interfaces and the implementation is sealed, do we get the same perf improvement? I think I recall changes around perf for interface dispatch. Guess we could do test it ourselves :D

  • @Barsikr
    @Barsikr Před rokem

    Those example int method numbers: Ah, I see you're a man of culture as well :D

  • @wultyc
    @wultyc Před rokem

    It would be nice if the language did that by it self maybe during the lowering process (not sure if that would make sense at this step) or even better making it sealed by default and having a config on the build process to change the behavior

    • @paulkoopmans4620
      @paulkoopmans4620 Před rokem

      they simply can not do that due to backwards compatibility. This is a long standing problem that affects anybody in software. For the dot net team it is no different than for yourself. As soon as you push something out the door, with focus on access levels, sealed or not, etc. your "customers" might be using your 'flaw'. Changing it is a breaking change.
      So the best they can do and have been doing for a while, is adding them as these checks and leave it up to you to treat them a certain way. Also the reason you should invest or use a proper IDE that makes you these suggestions for best practices.

    • @vasiliychernov2123
      @vasiliychernov2123 Před rokem

      There may be a class in another compiled assembly inheriting from the given class in current assembly. It's possible that they're linked only in runtime, so there's no way to know at compile time if the given class actually doesn't have any inheritors even if it doesn't have any in current assembly.

    • @wultyc
      @wultyc Před rokem

      I understand you both points of view and I do agree. I was just saying that I would like to somehow have this as default behavior of the language

  • @Zutraxi
    @Zutraxi Před rokem

    Will the performance gains also be there if your sealed class inherit from an interface.
    Or does the type check not matter in that case.
    In terms of the performance he mentioned

    • @nickchapsas
      @nickchapsas  Před rokem

      Interfaces are fine

    • @davidparker5530
      @davidparker5530 Před rokem

      Interfaces are not inheritance, but just forcing you to add set of methods with specific signatures to your type.

  • @xRalphy
    @xRalphy Před rokem

    Present!

  • @xybersurfer
    @xybersurfer Před rokem +6

    like many of your videos, i'm again wondering why the programmer is burdened with this trick, instead of the compiler or runtime doing this optimization. in this case the semantics of the program are also changed. it's a mystery what in .NET causes the slowdown

    • @traveller23e
      @traveller23e Před rokem +2

      Additionally, so little performance tips are readily available or found in documentation. Most of the tricks out there or "best practices" cite other goals such as readability or vague "better form". It's frustrating that even the stackoverflow questions regarding C are full of "just trust your compiler, it'll give you perfect results", let alone C#. And then to find out that the C# compiler doesn't automatically convert internal classes that aren't inherited to sealed, despite the performance benefit...although it also raises the question of whether this video is missing some nuance.

  • @mihcom123
    @mihcom123 Před rokem

    Can't we have an option for the compiler to automatically add sealed keyword to all internal classes with no inheritors?

    • @nickchapsas
      @nickchapsas  Před rokem +1

      You can make an analyzer that includes a refactoring. They might add the refactoring in .NET 7

  • @FudgeYeahLinusLAN
    @FudgeYeahLinusLAN Před rokem

    I avoid inheritance like the plage. I inherited (no pun intended) a project in 2010 where the previous developers made the mistake of relying heavily on inheritance, and it was an absolute pain to work with.

  • @ashlar64
    @ashlar64 Před rokem +7

    Interesting....One case you need to be careful is if you have created a nuget package / dll and you seal a class that would be very useful for your user to inherit from. This has happened to me and it caused me alot of pain.

    • @ArrovsSpele
      @ArrovsSpele Před rokem +3

      Absolutely agree. I cant imagine how i could survive till now, if i hadnt possibility to extend/inherit all kinds of 3rd party libraries.

  • @darkogele
    @darkogele Před rokem

    How about static classes vs internal, sealed, private ?

  • @SergeiFedorov77
    @SergeiFedorov77 Před rokem

    A beginner question: I have a Visual Studio project in .net core 3.1. Will these benefits apply for me in my .net core project?

  • @TomashPucko
    @TomashPucko Před rokem

    How about performance if we work with interfaces and use DI?

  • @poganezz
    @poganezz Před rokem

    Hmmm.. Why won't they make it configurable, like with nullables. So you can have sealed by default in your assembly?

  • @alphaanar2651
    @alphaanar2651 Před rokem +1

    8:26 I can see why you did that ;).

  • @mdonatas
    @mdonatas Před rokem

    From time to time it happens that you want to bend some library to your will or to intercept some internal state (by assuming full responsibility that it could break in the future!) and usually it would be impossible with sealed by default. Strictly from a crafty developer UX perspective - I despise sealed classes. I vote - no :)

  • @djupstaten2328
    @djupstaten2328 Před 8 měsíci

    It makes sense that classes with no Vtables by nature will have faster methods.

  • @proosee
    @proosee Před 9 měsíci

    Being someone who was integrating with legacy systems, "sealed" key word on public classes is most hated of them all for me - you just can't predict all the future of your system, so I would advice some humbleness on deciding what is something designed for. I know this is a bit of edge case and you can always use reflection, but still: I don't think we should focus on millisecond performance improvements when everywhere I look I see suboptimal algorithms, ridiculous data structures or architectural concepts that are pointless or harmful. And those I mentioned here are not even there as a trade off for readability or performance - quite the opposite in fact.
    Don't get me wrong, I praise developers of those legacy systems for domain specific device handling and such (that's why we were still using them), but you just can predict everything or you can just make a mistake of mixing few things that should be separate by accident.

  • @mohammadios
    @mohammadios Před rokem +1

    Can't they add open keyword and then have a optional property in project file to say classes are open or not by default? something like nullable or implicit usings. this way it's backwards compatible, and if you make new project template classes to be sealed by default it gets adopted more easily and just by that option being there it makes c# users search and know what the benefits are.

    • @bluesillybeard
      @bluesillybeard Před rokem

      Exactly what I was thinking

    • @paulkoopmans4620
      @paulkoopmans4620 Před rokem

      how? Maybe I am not seeing what you mean?
      the point would be that some old code from the 2000's like: public class X {} , stays a public and open class as you cannot infer whether or not it was intended to be sealed. This is the whole reason why you would have to 'close' it by adding it in the first place.
      They need to keep the compiler, runtime and JIT separate from IDE. I have said this in other videos too why adding a new keyword is not as simple as it sounds. Writing a lexer and parser is one thing. And to change it' to support a new keyword is ok, updating documentation also. But what if anybody out there has a class called open? or a variable?
      This is the reason the team has been favouring re-using existing keywords (like this in an extension method). They are guaranteed that nobody is using a keyword for something. And even if somebody did... they are doing with an @this.
      With the warning and the ability for you to treat it as a warning or error is the best they can do.

    • @gnack420
      @gnack420 Před rokem

      @@paulkoopmans4620 third party libraries imported from NuGet are already compiled it doesn't matter what their source code says.

    • @paulkoopmans4620
      @paulkoopmans4620 Před rokem

      ​@@gnack420 Of course it doesn't matter for already compiled libraries from nuget, or any source for that matter. I did not mention library in this response at all. The obvious problem is if you want/need to recompile old code.
      Btw; library obviously means two things; there is libraries (which we should call packages) that you can use from sources like nuget or proprietary downloads from a provider, but also every one of your 'project' in your 'solution' compiles to a class library as well.
      And I get the sense that a lot of people seem to be fortunate and only work on relatively new stuff, and that's great for them, but from experience I know that other people do have this battle in their day to day jobs; having some lingering code in the project that never gets touched and is over a decade old. And for this particular issue it could actually affect code created a couple of moths ago to be fair.
      it is these cases where the .NET team is making conscience choice to keep on compiling 'public class MyClass { ... }' to an 'open' or 'unsealed' class because they simply cannot guarantee it would not be inherited somewhere. So they are left with basically keeping it the way it is.... open by default and close it when you want it... because of backwards compatibility. And re-using the paradigm that they have been for a while... having the compiler spit out warnings that proper IDE's like Visual Studio, Rider, etc. can catch and help the developer take actions.
      Just imagine if you would work in a company with tons of legacy code and all of a sudden your build pipelines would fail building your code and you were now tasked with 'fixing' or 'patching' that, just because the compiler is now requiring you to add 'open'?
      Or you wrote a package last year that you are selling and you have 5000 customers using it. Your package is designed around a concept where your customers are allowed to inherit from a handful of classes. You run it through an updated compiler, which then closes all these classes that you actually intended to be open? Of course you would fix it... but the point is that the behaviour change of the compiler forced you into changing your code. Amplify this issue and that change might affect thousand's or tens of thousand's.

  • @badm0us3
    @badm0us3 Před rokem

    Hahaha 420. You and me have a lot more in common than just programming :)

  • @marekjaskua6774
    @marekjaskua6774 Před rokem +1

    Is there a way to seal the Program class and still use the Top level statement?

    • @nickchapsas
      @nickchapsas  Před rokem

      I actually don't know the answer to that but I don't think so

    • @ghidello
      @ghidello Před rokem

      @@nickchapsas I believe you can put "sealed partial class Program { }" in your Top level statement class

    • @marekjaskua6774
      @marekjaskua6774 Před rokem

      @@ghidello It works ;) Thx, demons and classes should be sealed forever

  • @huynguyenphan4120
    @huynguyenphan4120 Před rokem +1

    Is there a way to get this analyzer work with Unity?

    • @nickchapsas
      @nickchapsas  Před rokem +1

      It’s a pretty simple analyser so I am assuming you can yoink it from the repo and use it as a nuget package