The New Way of Calling Your Code in .NET 8 Is INSANE

Поділитися
Вставка
  • Опубліковано 28 вер 2024
  • Use code DOCKER15 and get 15% off the brand new Docker course on Dometrain: dometrain.com/...
    Become a Patreon and get source code access: / nickchapsas
    Hello, everybody, I'm Nick, and in this video, I will introduce you to an extremely powerful feature added in .NET 8 called the UnsafeAccessor. This feature aims to replace reflection on many levels and provide compile time performance but also allow for NativeAOT support.
    Subscribe to Dan: @danclarkeuk
    Workshops: bit.ly/nickwor...
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: bit.ly/ChapsasG...
    Follow me on Twitter: bit.ly/ChapsasT...
    Connect on LinkedIn: bit.ly/ChapsasL...
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

КОМЕНТАРІ • 547

  • @gustavo-santos-dev
    @gustavo-santos-dev Рік тому +414

    This is probably a crime in +50 countries.

    • @dextergandini
      @dextergandini Рік тому +18

      It is also forbidden by Genebra convension!

    • @fakhrulhilal
      @fakhrulhilal Рік тому +3

      It means we can do anything what we want to be in any framework we’re using😂

    • @mattkins99
      @mattkins99 Рік тому +8

      OMG I don’t want to support this when I find it 10 years from now in a class that starts with the comment // Don’t touch, thar be dragons

    • @adambelos2157
      @adambelos2157 Рік тому +1

      Mama i am a criminal...

  • @clementdato6328
    @clementdato6328 Рік тому +307

    Finally, I can change the value of a static private read only field of a class in some other person’s code so that when another person use my library they will learn to read through all code before actually believing something is read only and private.

    • @Spid88PL
      @Spid88PL Рік тому +20

      INSANE

    • @fifty-plus
      @fifty-plus Рік тому +23

      Make sure your comments are totally off base too 😉

    • @IvanRandomDude
      @IvanRandomDude Рік тому +19

      Truly a gAmE-cHaNgEr

    • @erynmacdonald
      @erynmacdonald Рік тому +5

      WARNING *sarcasm* DETECTED

    • @phizc
      @phizc Рік тому +12

      You could have done that in previous versions of .NET too. It's just become a more pleasant coding experience to do so now 😛.

  • @KieranFoot
    @KieranFoot Рік тому +184

    I'm guessing this is part of getting rid of reflection for AOT...

    • @peanutcelery
      @peanutcelery Рік тому +11

      Yeah a lot is being set up for AOT like minimal apis.
      I feel like .NET 8 was the setup to make AOT more common for the next .NET versions.

    • @z0nx
      @z0nx Рік тому +4

      Interesting.. Is it because this can be done at compile time or something?

    • @renauddanniau676
      @renauddanniau676 Рік тому +3

      @@z0nx Exactly, I think they will combine this with source generator to generate code at compile time and not during runtime ;).

    • @RiversJ
      @RiversJ Рік тому +2

      Yup Native AOT plays a big role in .Net 8

    • @davidfowl
      @davidfowl Рік тому

      @@peanutcelerySomebody has been paying attention 🫡

  • @woocaschnowak
    @woocaschnowak Рік тому +34

    With great power comes great responsibility.
    Don't use your power to change static readonly fields :D

  • @OlofLagerkvist
    @OlofLagerkvist Рік тому +17

    Great video, but I think one additional way of doing it should have been in the benchmark. That is, getting the MethodInfo object through reflection, then build a Func (or similar) delegate of it and then cache that delegate and call that instead of using the dynamic Invoke() method each time. Many years ago I changed that in lots of places in a code base that had a lot of reflection and improved performance a lot. The question now is how that compares to this new way of doing it!

    • @TheMonk72
      @TheMonk72 Рік тому +4

      I routinely use LINQ lambda expressions to build funcs for methods I'm accessing via reflection because they're faster than invoking a MethodInfo. And they work well with generics. Would love to see a speed comparison with this.

  • @Demonata1223
    @Demonata1223 Рік тому +7

    I had a very good use case for this recently. We use private constructors for some of our objects because we want to tightly control how new things are made. But that inadvertently effected serialization. System.Text.Json cannot serialize with private constructors. Newtonsoft can. Thats an example of when something is private. but you may still need to access it externally in some situations. I dont want to open up something thats private in the code base but i still want to be able to serialize/deserialize it properly.

  • @PereViader
    @PereViader Рік тому +38

    Compile time performance is the best part of this ❤

    • @parlor3115
      @parlor3115 Рік тому +2

      I don't think it matters since you're mostly going to use this in tests where you run your methods a few dozen times each at most.

    • @BillyBraga
      @BillyBraga Рік тому

      You can probably get the same perf with reflection if you compile lambda expressions

    • @neppe4047
      @neppe4047 Рік тому

      ​@@BillyBragayeah I think he did something like that in another video, not sure why didn't in this one

  • @dhochee
    @dhochee Рік тому +12

    "It's a pain ... where you don't want to be painful" is hilarious. I'm gonna steal that. Regarding the main topic ... I've used reflection to access private members before, but only when it was an abstraction designed to handle cases where you don't know the member names at design-time. This new feature doesn't help with that, so it's just ignoring the original developer's intentions. I suppose if you absolutely need to do it, having it be declarative with "Unsafe" in the keyword is better than hiding it behind reflection. Also much faster, of course, as you observed.

  • @ristopaasivirta9770
    @ristopaasivirta9770 Рік тому +22

    Who would win: ten years of SOLID principles vs one unsafe boi?

  • @TheRicherthanyouguy
    @TheRicherthanyouguy Рік тому +33

    I’m so mixed on this I can definitely see value from a unit testing perspective because there are codebases that have private methods that really have too much going to be private. Which really just needed to be rewritten. I strongly dislike accessing things that should be private purposefully but I also love the performance boost

    • @leerothman2715
      @leerothman2715 10 місяців тому +1

      I can see it being useful for testing DDD classes that have immutable properties on a test fixture setup. Not sure I’d use it for executing private methods though. Unit tests should be decoupled from the implementation of the subject under test.

    • @TheRicherthanyouguy
      @TheRicherthanyouguy 10 місяців тому

      @@leerothman2715 agreed I think we are all mostly on the same page of this can be useful but only in rare or extreme situations.

  • @BillyBraga
    @BillyBraga Рік тому +46

    Personally, I think a valid use case is when you are using a nuget package that doesn't expose the functionality or configuration required for functioning properly in your app.

    • @MayronWoW
      @MayronWoW Рік тому +6

      I've had this problem a number of times. One example has been when a package is serializing data using its own internal serializer and does not provide any configable settings or callbacks. This has prevented me from using custom logic required by an app I was working on. It's good to open up an issue on their pull request but that could delay your code from going live or completely block you if they choose to ignore your issue for years.

    • @phw1009
      @phw1009 Рік тому +1

      That will be very useful, especially on nuget packages those not maintained anymore.

    • @noon9548
      @noon9548 Рік тому +1

      ​@@phw1009how would you improve the packages that not maintained anymore? Do you mean changing inners of packages or extending functionality?

    • @davidmartensson273
      @davidmartensson273 Рік тому

      @@noon9548 It could be enough to be able to access some internals to be able to work around a problem.

  • @anm3037
    @anm3037 Рік тому +1

    The first place I will use it is to grab the array under List

    • @mbenoni7397
      @mbenoni7397 Рік тому

      You can already do that with CollectionsMarshal.AsSpan()

  • @IllidanS4
    @IllidanS4 Рік тому +3

    I love nothing more than ways to break guarantees in a runtime (but readonly fields were modifiable before using... ways). Anyway I feel your performance benchmark is missing the case when you call the method via a delegate, as that is the "proper" way of binding to it (as opposed as Invoke having to perform argument unboxing and whatnot before getting to the method). Perhaps throw a function pointer into the mix as well.

  • @PeterOeC
    @PeterOeC Рік тому +1

    My mind was blown once, when my colleague showed me how to make a self-updating const in JavaScript.
    Now you're showing me that private properties can be changed from outside classes 🤯
    I need to sit down

  • @DemoBytom
    @DemoBytom 11 місяців тому +1

    This is gonna be used in source generators so much, and I'm 99% sure that was the main reason the feature got introduced to the runtime.
    In pre .NET 8, to extend a class with source generator you have to make the class partial, and then have the generator create the extension in the class' partial.
    With this feature we will be able to extend non partial classes, just as if they were, without bloating said class with the generated methods, you might NOT need outside of what the generated code was for. This is an amazing, though very dangerous, thing indeed.

  • @metaltyphoon
    @metaltyphoon Рік тому +4

    If all the reflection based methods on the BLC gets to use this feature under the hood, then most reflection code can be AOT compatible

    • @Alex-ABPerson
      @Alex-ABPerson Рік тому

      That doesn't really work because the parameters on the attributes need to be _constant_ - while reflection obviously only knows what strings it's getting when it's executed.

  • @benjaminclehmann
    @benjaminclehmann Рік тому +18

    I'm wondering if this is safer, for example if the method doesn't exist or the signature is incompatible would this fail at compile-time? Because in that case this seems like a massive win, especially for those who are committing these types of sins on code they don't have access to.

    • @marton-vincze
      @marton-vincze Рік тому +2

      I highly doubt that compile time checking for private field are possible, the input parameter for the accessor can be typed as an interface or an abstract class where some implementations will possibly have this method/field

  • @MikeZadik
    @MikeZadik Рік тому +1

    This can help to fit or fix problems in 3rd party components when you have access to the source code, but you don't want to build your own version just to change that one read only value to activate tls or something like that.

  • @ja_mcito
    @ja_mcito Рік тому +6

    Maybe it's just for use in highly optimized libraries

    • @SimpMcSimpy
      @SimpMcSimpy Рік тому +3

      Perf is only one reason but no the main one. It's mostly for AoT and code trimming scenarios where reflection can't figure out what to take out or what to leave.

    • @Daniel15au
      @Daniel15au Рік тому

      ​@@SimpMcSimpyThe property name is still a string though, rather than a static reference... Will this help with AoT?

  • @kconfesor
    @kconfesor Рік тому +3

    This will be really useful for mocking libraries and testing 😊

    • @cgeorgescu72
      @cgeorgescu72 Рік тому

      Will be really useful for messing up with the juniors in your team: overwrite their readonly int=1 then let them struggle a day to understand why it doesn't pass the test.

  • @hichaeretaqua
    @hichaeretaqua Рік тому +1

    I think this is a good approach to access private things if there is no other way. But I'm glad we have code reviews and hope tampering with private things never gets through...

  • @1dfe-4e68-bd9f
    @1dfe-4e68-bd9f Рік тому +21

    .NET developers before:
    C++ is unsafe, so we invented delegates in C#
    .NET developers now:
    Now we can call functions in unsafe manner as C++
    Great job!🤣🤣🤣

    • @ebubekircagrsen7824
      @ebubekircagrsen7824 Рік тому

      This is gentlemans, worst way to criticize

    • @jean-michelgilbert8136
      @jean-michelgilbert8136 Рік тому +1

      LOL. This is worse than any bad pattern in C++. It lets any class call and modify private methods and fields easily. The next time I see a C# developer ranting about the friend keyword in C++, I'm countering with this 🤣

    • @JacobSnover
      @JacobSnover Рік тому

      C# has had unsafe keyword since the start, they avoid it by default to save devs from tedious operations and to be 'more safe', but it's always been there. C# is used in different applications than c++ making unmanaged code much less needed.

    • @SimpMcSimpy
      @SimpMcSimpy Рік тому

      @@jean-michelgilbert8136
      This is expected when you are redesigning JIT compiler to support AoT.
      They run into wall with reflection and trimming.

    • @KurtVanBever
      @KurtVanBever Рік тому

      Your observation is correct but I think you are drawing the wrong conclusion. Remember that the type safety was not put in place because type safety is a wonderful thing in and of itself. The main purpose behind it was the almighty dollar: type safety results in fewer bugs, so development goes faster and as you know time is money.
      As said in the video MS made this feature because there are some solid use-cases for it. You could take the perspective that they are running back to C++, and in some sense that is exactly what they are doing. But the fact is that this is all part of an ongoing, more elaborate, evolution. In the same category you will find for example CYTHON (Python running back to C++).
      I think we should get used to the arrival of new or renewed languages that will put the best of both worlds together. Transition will be like going from an automatic car to driving a stick. I think it will benefit all of us.

  • @JohnAndrews_nz
    @JohnAndrews_nz 5 місяців тому

    I wouldnt use this for private, but the performance boost, often we use reflection on a "object" where we knnow that object has a property/method, that doesnt have a common interface to expose it, that this could then be used to call that public property/method to get/set that value.

  • @Neonalig
    @Neonalig Рік тому +7

    Probably going to be eons before Unity updates to .NET 8 (if its even around then given their current dramas), but when it does, this will really change editor scripting for the better. So many useful methods and classes are needlessly internal or private, resulting in tons of required (cached) reflection or even IL emission to do anything even remotely advanced.

    • @mysteriousmop7686
      @mysteriousmop7686 Рік тому +5

      ...and if we're lucky, they'll only charge developers $150 per .NET major version!

    • @TheGalantir
      @TheGalantir Рік тому

      Unity is dead even with their new price change as trust is not adressed.
      Try Stride instead they're reasonably up to date with their .NET version.

    • @DynamicalisBlue
      @DynamicalisBlue 4 місяці тому

      Some people still haven't moved to Unreal/Godot yet?
      Unreal exposes a lot and lets you override almost everything, and for the very few things you can't, you can modify the engine directly.
      Can't speak for the exposedness of Godot but at least it's open source so you can still do what you want.

  • @nocturne6320
    @nocturne6320 Рік тому +3

    This is an amazing feature, only a shame that you haven't included a benchmark for a compiled lambda as well.

    • @AlwaresHUN
      @AlwaresHUN Рік тому +2

      Its great till my colleagues don't know about it :D

  • @modernkennnern
    @modernkennnern Рік тому +4

    How does this interact with string.Empty? I remember reading that it used to be changeable but they fixed that. Does this reintroduce the possibility of changing it? It's a static readonly after all

    • @nickchapsas
      @nickchapsas  Рік тому +8

      I tried. You can't set its value since its marked as a JIT intrinsict

    • @modernkennnern
      @modernkennnern Рік тому

      @@nickchapsas that's great

  • @AlFasGD
    @AlFasGD Рік тому +3

    I got ill just by hearing your voice, get well soon Nick

    • @nickchapsas
      @nickchapsas  Рік тому +1

      Damn I didn't know people would notice! Thanks ❤

  • @DivingDeveloper
    @DivingDeveloper Рік тому +1

    Thank you for this, Nick. Concise and helpful as always. I can see the use - as you demonstrated - clean and fast running, if potentially dangerous code.

  • @ehudv9276
    @ehudv9276 Рік тому +1

    In "powerful" you mean "I've done mistakes in the design so I have to break encapsulation, but I want some syntactic sugar on it so my boss will think I'm doing a good job"
    You'd be better shooting your own foot.

  • @thunderdeer6073
    @thunderdeer6073 Рік тому +1

    Sometimes you gotta do what you gotta do

  • @marsgal42
    @marsgal42 Рік тому +3

    This looks like one of those features where you may only need it once a year. But you'll *really* need it.

    • @tchpowdog
      @tchpowdog Рік тому +2

      This is how I feel. If you have to use this against your own code, then your design is bad. This just looks like a hack for 3rd party libraries... which I'm not in favor of. I feel like if you use this regularly, then you're doing a lot of things wrong. In my 13 years of development, I could maybe point to 2 or 3 times where it would have been nice to access private members of a 3rd party class - but there was always some other solution. I'm kind of surprised Microsoft is releasing this.

  • @F1nalspace
    @F1nalspace Рік тому

    This is awesome! I had some cases in the past, where i had to use reflection to get a private value out - and it was very slow.
    Great that there is now a tool for doing the same thing - and more, for compile time performance. I like it ;-)
    Thanks for sharing.

  • @frankquednau889
    @frankquednau889 Рік тому +2

    Kinda OK with having this. Just yesterday I had to use some internal setters for tests involving types of the blobstorage lib. But allowing this to break promises like static readonly seems to me *absolutely bonkers*. Really.

  • @JorneDeSmedt
    @JorneDeSmedt 11 місяців тому

    Seems useful for unit testing your private methods.

  • @jc_alpha
    @jc_alpha Рік тому

    4:17 “It doesn’t take a genius to understand that having to write something like this *every single time* is very very tedious”
    You make it sound like this is the first thing we do every morning before standup.

  • @innerbytes
    @innerbytes Рік тому

    I see it very usefull for testing in some scenarios.

  • @mclifeleader
    @mclifeleader Рік тому

    As a developer and an engineering manager, I can say that as helpful as this maybe it wreaks of code smell!

  • @元始天尊-b7k
    @元始天尊-b7k Рік тому

    This is Assembly Publicizer which has been available for a long time in modding community

  • @99aabbccddeeff
    @99aabbccddeeff Рік тому

    It's really helpful feature in some rare cases. Thanks for the sharing.

  • @the-niker
    @the-niker Рік тому +4

    Ooof.. I sense a major rewrite in my future. How is the compatibility with older .NET7 or 4.8, can you multitarget to those and compile or do you have to #if NET8_0_OR_GREATER and write the reflection version anyway?

    • @Daniel15au
      @Daniel15au Рік тому

      This is likely a compile-time feature, meaning it should be possible to compile to a .NET 4.8 target. I haven't tried it though. It'd likely just compile to the old-style reflection code when targeting older runtimes.

  • @bayoucaneboy9332
    @bayoucaneboy9332 Рік тому +1

    The fact that this is promoted as an improvement just shows that Microsoft is not understanding what other languages and editors are doing with meta programming and treesitter. While C# has things like "nameof" that might help avoid the use magic strings, they release this feature that further propagates their use.
    Don Syme understood this with Type Providers. Ultimately, C# is becoming such an utter mess it's disappointing.

  • @ForeverZer0
    @ForeverZer0 Рік тому

    I am totally opposed to the thinking that "too much power" or "is too unsafe" in a language. C# suffered from this thinking for a very long time until recent years when they begin adding some more powerful features and better management over arbitrary memory. A "safe" language should have all the guardrails in place, but completely removing the ability for the programmer to explicitly bypass them can be frustrating where there is something non-standard that needs done.
    Building and emitting IL at runtime was previously the next best thing to do other than just using a different language, so I am glad to see MS putting some more power and trust in programmers.

  • @darthruneis
    @darthruneis Рік тому +1

    I have an actual use case for this that I'm dealing with right now, but unfortunately its on Net Framework, so this wouldn't really apply. Its on an old MS library for OIDC support on OWIN, so its a good use case in the sense that the code is very mature and very unlikely to change, and also the implementation is not extension-friendly (its all private/internal, not protected and/or virtual).
    So, I guess I'm stuck with the reflection code (or copying their implementation verbatim from github).

  • @user-nq8ln7ps7x
    @user-nq8ln7ps7x Рік тому +1

    I wonder if it can be used with generic methods/interfaces as well? It's always pain when some libraries only expose generic methods, so you have to live without polimorthism and specify concrete generic interfaces, or create some non-generic decorators with lots of delegate generation / caching / casting. For example: Kafka producers in MassTransit

    • @alexisfibonacci
      @alexisfibonacci Рік тому

      I instead create a lightweight generic wrapper with non-generic interface implementation. Instantiate that wrapper per type and cache the wrappers in a dictionary with the Type as the key. When needed, do the lookup, call to the instance to get the work done, and move on.
      But I guess .NET 8 can simplify all of that and we get to delete some code.

  • @derhinek
    @derhinek Рік тому

    The only thing I can think of, where it makes sense to access private members would be in tests. Microsoft has/had an way for this in their own test framework using a class I think called PrivateObject.

  • @GTSJoeG
    @GTSJoeG 9 місяців тому +1

    Which editor is he using? Doesn't look like Visual Studio nor VS Code.

  • @bachph
    @bachph Рік тому +1

    With great power comes great responsibility! 🕷

  • @reirei_tk
    @reirei_tk Рік тому

    Oh man, once you said the word "extern," I knew I was in for a wild ride. But then I was like, "alright, well, good thing I try to make stuff read-only whenever I can," but then you edited the static read-only field. Well, RIP to that idea. This was all pretty crazy, but that put it over the top.

  • @The_Genezis
    @The_Genezis Рік тому +1

    every time he said "the name is" I filled "Primogean" in my head. Please help

  •  Рік тому +15

    My prediction is that in a few years c# documentation will be bigger than the bible. The fields and classes will have some 15 keywords to define them. I'm now waiting for AI related keywords to brought into the language. 🎉🎉

    • @peanutcelery
      @peanutcelery Рік тому +5

      Right there are so many methods and properties added every update. I came from Java and I’m like damn this language updates slow but then I came to C#…

    • @solovoypasando
      @solovoypasando Рік тому +1

      @@peanutcelery c# is moving way too fast now I understand why Java is more popular, there's no way to keep up with C# and have a life at the same time

    • @cgeorgescu72
      @cgeorgescu72 Рік тому

      Yeah, it will be like:
      [ChatGptImplemented]
      public partial int GetWeatherForCity(string city){}
      and will automatically fill the method body for you at build time. And will write a personalised resignation letter as well.

    • @Yudikab
      @Yudikab 11 місяців тому

      @@solovoypasando hell yaa.i moving to open source soon enought

  • @TheLatyos
    @TheLatyos Рік тому

    Nick: *extern* you probably haven't seen this keyword before.
    Me, who interops C/C++ to C# for a living: Yeah Nick, I wish. I really wish.

  • @CodeFun691
    @CodeFun691 Рік тому

    Just straight up breaking encapsulation and you are also proud of this "insane" feature. Bury this deep in the documentation and let only people know that actually know what they are doing. The rest can move on, there is nothing to see here.

  • @BoleslawMalinowski-u2u
    @BoleslawMalinowski-u2u Рік тому

    Might the reason of introduction of such logic was better support of Roslin-like compilations, as in case of Reflection those examples just wouldn’t work?

  • @jacquesdemolay2699
    @jacquesdemolay2699 Рік тому +2

    Could you give examples of when we MIGHT need to access a private method ?

    • @markmidwest7092
      @markmidwest7092 Рік тому +2

      Unit tests

    • @arjix8738
      @arjix8738 Рік тому +1

      One great example is modding Unity games!
      Although when modding you'd probably use a fake assembly as ur reference, so the compiler thinks that everything is public (lookup NStrip)
      (yeah this didn't age well)

    • @stxnw
      @stxnw Рік тому

      @@arjix8738 "so the compiler thinks that everything is public" are you talking about injecting code into the unity process? because I still have to use reflection to access private variable if I am injecting.

    • @toebeann
      @toebeann Рік тому

      ​​@@arjix8738Assembly Publicizer has been my go-to for the same purpose, but I see NStrip is made by the BepInEx creator so I will give it a look too!
      Do somewhat wish this new API existed back in .net 4 or something so we could use it instead of publicizing all members (I much prefer the idea of only publicizing those members I need rather than everything - less footguns that way!)

  • @MichaelMortensen
    @MichaelMortensen 10 місяців тому

    Wonderful insights, thanks!

  • @aprobinda
    @aprobinda Рік тому +1

    Thanks for the awesome demo, Nick!
    I don't think it's something that I am going to use in the near future. Plus, I am not aware of scenarios that warrant messing with private members of classes in a C# app code.
    Perhaps, other viewers would describe such scenarios?

    • @SimpMcSimpy
      @SimpMcSimpy Рік тому

      It's mostly for Ahead of Time compilation.

    • @Quasindro
      @Quasindro Рік тому +3

      Video game modding is also a good example (though modders DEFINITELY were not the target Microsoft was aiming at 😂)

    • @mindstyler
      @mindstyler Рік тому

      Quite a few in frameworks/engines like Unity. E.g. editor extension and code reuse you otherwise would have to write yourself from scratch.

  • @TheSlimshader
    @TheSlimshader Рік тому

    This is a great tool in combination with source generators

  • @iiTzluffy
    @iiTzluffy 11 місяців тому

    I see a problem with this, the fact that we can access unused private methods, while it is technically being used. It still says the private method is not used and it is safe to remove. Doing an auto cleanup or removing some unused code can be dangerous now no? Thoughts?

  • @rmcgraw7943
    @rmcgraw7943 6 днів тому

    Does this work for with the BCL too? If so, then it makes all of the BCL virtual, seemingly.

  • @aj.arunkumar
    @aj.arunkumar Рік тому

    1 year from now nick will go like "now Im become death, the destroyer of clean codes"

  • @samuelschwager
    @samuelschwager Рік тому +4

    In C++ you can just do #define private public, infinite performance! :P

    • @jean-michelgilbert8136
      @jean-michelgilbert8136 Рік тому +1

      That violates the One Definition Rule though. A cleaner solution would be to add a #define HACK_ClassNameToUse ClassName inside the 3rd party header file. Put that inside an #ifndef HACK_ClassNameToUse . Then, rename the class to HACK_ClassNameToUse . Also make sure to change the private: keywords to a custom private_or_public: keyword that is defined to private when using the original name of the class and public otherwise. Afterwards, you can reinterpret_cast to the renamed class to access private fields and methods. Congratulations, you have broken encapsulation in C++ of a 3rd party lib without breaking the One Definition Rule. I'm insisting on the code being 3rd party because, if the code is 100% yours, you can just add the friend keyword to the class and be done with it.

    • @xlerb2286
      @xlerb2286 Рік тому +1

      My favorite was #define struct union ;) Did that to a buddy once in college about 30 years ago. We loved pulling those gags on each other. He got me back.

    • @samuelschwager
      @samuelschwager Рік тому

      @@xlerb2286 damn, that was mean ;)

  • @privatesocialhandle
    @privatesocialhandle Рік тому +2

    My favorite .NET guy. Always energy and excitement.

  • @Gavin556
    @Gavin556 8 місяців тому

    this is what you need for writing unit test when you don't want to expose everything as public

  • @bsoter
    @bsoter Рік тому

    I can almost hear typing noises of dotnet tech leaders updating their teams' code guidelines in 'Forbidden techniques' section xD

  • @andersborum9267
    @andersborum9267 Рік тому

    It provides the same end result for the developer, but comes with a significant perf improvement; setting protected members using reflection has been a thing for years using reflection.

  • @twiksify
    @twiksify Рік тому

    I actually think that UnsafeAccessor is safer than the previous example using reflection.
    Using the attribute; the class name, method name and kind needs to be known at compile time.
    Using reflection you can traverse and call unknown code, which I think is way more unsafe.

  • @JustArion
    @JustArion Рік тому +1

    I would have preferred an Attribute to this. Though it is still a step in the right direction. Roslyn has/had something similar with the [assembly: IgnoresAccessChecksTo("assemblyName")] Attribute. Wonder if the boilerplate can be source-genned away or some notification can be shown if the member you're trying to target no longer exists.

  • @briantaylor7695
    @briantaylor7695 11 місяців тому

    Any idea if it works with Local functions, if so that would be so useful for unit testing

  • @michaelvanstraten4390
    @michaelvanstraten4390 Рік тому

    Microsoft: *pulls out hand grenade, removes safety pin and hands it to you* > here you go

  • @slyp05
    @slyp05 Рік тому

    Are they going to powercreep the private keyword, and give us a "CannotBeUnsafeAccessed" attribute in the future?

  • @SchadenNZ
    @SchadenNZ Рік тому +7

    This makes me wonder if it would have a place in testing. Sometimes I want to access a value that should be private so as a work around I would change it to internal and allow internal access to the test project. With this new code I'm assuming i could leave it private and still access it?

    • @AlFasGD
      @AlFasGD Рік тому +17

      You should never perform behavioral testing, like exposing its inner components and testing how they are adjusted behind the scenes. You should only care about the exposed side effects, your current public state and whether your code does what it is supposed to do. If you feel like you have to use this during testing, you are either doing something unsafe in nature, or you are simply not doing something good and need to test something more important.

    • @rab1d78
      @rab1d78 Рік тому +4

      @@AlFasGD While I agree, I can think of a use case for testing. Large old crappy code bases that weren't written with tests in mind. Classes that don't follow SRP, but have private methods that go and gather data and such. If they work well enough to not warrant a rewrite but could use some unit test coverage... I would want to think about it longer but the potential...

    • @AlFasGD
      @AlFasGD Рік тому +1

      @@rab1d78 Legacy codebases are always the exception to the rule. That's the scenario that this feature is primarily intended for; legacy systems and libraries that barely hold things together. Writing tests even for observational purposes could also help ensuring that you know what to expect in certain scenarios.

    • @ronsijm
      @ronsijm Рік тому

      @SchadenNZ yes sure. What I usually do is create a source generator for my test project, that creates private method accessors through reflection.
      With this new UnsafeAccessor you could do something similar

    • @SchadenNZ
      @SchadenNZ Рік тому

      @@AlFasGD Theory is all well and good but try working on a code base that is over a decade old, was written without any consideration for testing, has been modified so many times that no one knows the purpose of large sections of code, serves half a BILLION requests a month with a $10k per minute SLA penalty --- and the ticket wants you to add a few tests to increase confidence all the while changing as little as possible.
      Don't expose inner components is so far down my list of priorities that I'd have to take an elevator to get there. 🤹

  • @davidmatten8519
    @davidmatten8519 12 днів тому

    I would never be allowed to check something in that uses this outside of a debugging of library code we don't control. It would never be allowed into Production.

  • @DotNetCookbook
    @DotNetCookbook Рік тому +3

    I don't know, most of the time you would use reflection when you don't know the member name at compile time, and this approach does not apply to such scenarios because it uses attributes. I agree there might be some use cases for it - e. g. getting more convinient and performant way to access private members, but it's so rarely needed that I wouldn't call this something super powerful.

    • @astrowalker2629
      @astrowalker2629 Рік тому

      The most important use case is testing. Now I have to turn my private method to internal, which is far worse for me.

  • @wknight8111
    @wknight8111 Рік тому +2

    Oh my goodness I do not like this at all. For most "normal" code I would absolutely refuse to merge something like this. It would have to be an extraordinary or niche situation, and I would want to make sure there were plenty of comments and lots of documentation around it to make sure everybody knew what was going on. Visibility modifiers and readonly tags have meaning, and going around those things violates the Principle of Least Surprise in a stunning way (not to mention basic rules of encapsulation, etc).

  • @KyriakosStergiou
    @KyriakosStergiou 4 місяці тому

    "Hello everybody i'm naked in this video", subtitles are getting really interesting here

  • @Misteribel
    @Misteribel Рік тому

    Is this a compiler feature or a dotnet feature? That is, does it get desugared by C#, or does it work with any language?
    PS reflection is usually used with names or other member or class features nor known at compile time. Once you know it statically, like in your example, you can use existing tricks to make it as fast (cache and use delegate) as a normal method call. Of course, this approach makes certain use cases simpler, but does not replace reflection.

  • @anonimzwx
    @anonimzwx Рік тому +3

    I think it is useful to test private methods, but i think it is a bad practice in non-testing code because if you have something private shouldnt be called from others classes and if you need to do it then you have an issue in your code and you should fix it

  • @nmarcel
    @nmarcel Рік тому

    I only access private members when needed for Unit Testing, and therefore I would prefer a way to tell any assembly that another one is for testing and let it have plenty access to its private members instead of all this boilerplate.

  • @gani7485
    @gani7485 11 місяців тому

    Thanks, Its a good one, But I have a small question,
    you are calling the private method outside that class.
    Q1: But why?
    Q2: you are calling that private method inside a public class and public method, instead can't you make the private method public?

  • @nnguyetnam
    @nnguyetnam 11 місяців тому

    Nice feature, but in term of software quality, i am not sure if general developers should use it. Especially, if we are working in a team and your code is hard to read and maintain by others

  • @tiendatniit
    @tiendatniit Рік тому

    Could someone help me to explain why 10 years before They referred to use the of reflection?. It's really painful to debug in the huge system.

  • @jimwithheld7217
    @jimwithheld7217 Рік тому

    So I have a private var inside my class, and I 100% trust it only holds 1 of 4 values that my method calls allow. But now it might be any other value too. How on earth is safe and tested code possible with those kinds of rules at play?

    • @toebeann
      @toebeann Рік тому +2

      If someone messes with your code and changes the private value to something unexpected and it breaks, it isn't your job to support them beyond saying "yeah, don't do that."
      Using reflection and other means to access private members have existed in .NET for a long time, there is nothing you are seeing in this video that wasn't already possible some other way. It's just a new API for doing it with the same performance as it it were public, and that's already possible, via even more unsafe means.
      So, treat private the same way you always have. Most users of your libraries etc. won't ever think about trying to access private members, and those that do will almost never come crying to you about it if they break something in the process, because they should know better.

  • @DanielFerreiraMonteiroAlves
    @DanielFerreiraMonteiroAlves Рік тому +1

    For sure I'm gonna use that! Imagine this while generating proxies for decorators, ORMs, etc! It might allow the tool to be not intrusive but with all expected behavior and almost no performance hit!

  • @zabustifu
    @zabustifu Рік тому

    Your non-cached reflection method uses GetType(), while your cached reflection method uses typeof(). The latter should perform better. I'm surprised you didn't do the same in both, for consistency. That said, I guess the end results wouldn't be that different.

  • @parcanapp1193
    @parcanapp1193 Рік тому

    Great for testing. No hit in runtime, production code doesn't need to change to accommodate testing infrastructure.

  • @knifekitty_ls
    @knifekitty_ls Рік тому

    can you get static field of Method() and replace it with new Func that has completely different implementation?

  • @lordmetzgermeister
    @lordmetzgermeister Рік тому

    I assumed the compiler generates the references at compile time, but according to documentation the implementation is generated by the runtime.
    How the heck is it so fast then?

  • @Zalmakiz
    @Zalmakiz Рік тому

    wow this is dangerous, but also cool!

  • @borisgomiunik7960
    @borisgomiunik7960 Рік тому

    Could it be that Microsoft has added this to gain extra nanoseconds in EF core? To really try to win the speed race with dapper? As much as I understand EF core uses reflection under the hood.

  • @Dimich1993
    @Dimich1993 Рік тому

    It's great and your videos are great.

  • @mad_circuits
    @mad_circuits Рік тому

    The idea behind "private" is to not interfere from the outside. It's considered bad code, and if you believe you need to access such a member property, method, or field, you're likely making a mistake. Big time!

  • @vm123
    @vm123 Рік тому

    How abouth where there is more than one method with the same name (overloaded)?

  • @sunefred
    @sunefred Рік тому +2

    Auto-reject if I see this in a PR

  • @gideonharmse4270
    @gideonharmse4270 Рік тому

    I really want to buy your courses since they look really cool, but as a South African, it's just too expensive because our currency is so weak; could you supply South Africa discount codes?

  • @isnotnull
    @isnotnull Рік тому

    What about generic methods? Calling them was the most painful for me?

  • @MrNotour
    @MrNotour Рік тому

    The only allow use case i see is to easy testing, through unit test, more deep code part without changing the protection to internal.

  • @Micke2nd
    @Micke2nd Рік тому

    So if we use a 3rd party component, with a license check inside, and its result is cached in a private field - we can set it as we like ? To demotivate developers to sell solutions ?

  • @DavidSmith-ef4eh
    @DavidSmith-ef4eh Рік тому

    I want to call private methods in unit tests in php. It should be possible, no discussion!

  • @HighwaysTravel
    @HighwaysTravel Рік тому

    Do we really need this practically?

  • @quetzalcoatl-pl
    @quetzalcoatl-pl Рік тому

    You totally mixed up 'readonly' with true consts. 'readonly' exists only in C# language, it is NOT handled by CLR. Contrary to what you said, reflection in C# has not a slightest problem with modifying readonly fields, contrary to what you say at 12:04