Тёмный

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

Nick Chapsas
Подписаться 308 тыс.
Просмотров 138 тыс.
50% 1

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

Опубликовано:

 

4 окт 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 548   
@gustavo-santos-dev
@gustavo-santos-dev Год назад
This is probably a crime in +50 countries.
@dextergandini
@dextergandini Год назад
It is also forbidden by Genebra convension!
@fakhrulhilal
@fakhrulhilal Год назад
It means we can do anything what we want to be in any framework we’re using😂
@mattkins99
@mattkins99 Год назад
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 Год назад
Mama i am a criminal...
@KieranFoot
@KieranFoot Год назад
I'm guessing this is part of getting rid of reflection for AOT...
@peanutcelery
@peanutcelery Год назад
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 Год назад
Interesting.. Is it because this can be done at compile time or something?
@renauddanniau676
@renauddanniau676 Год назад
@@z0nx Exactly, I think they will combine this with source generator to generate code at compile time and not during runtime ;).
@RiversJ
@RiversJ Год назад
Yup Native AOT plays a big role in .Net 8
@davidfowl
@davidfowl Год назад
@@peanutcelerySomebody has been paying attention 🫡
@clementdato6328
@clementdato6328 Год назад
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 Год назад
INSANE
@fifty-plus
@fifty-plus Год назад
Make sure your comments are totally off base too 😉
@IvanRandomDude
@IvanRandomDude Год назад
Truly a gAmE-cHaNgEr
@erynmacdonald
@erynmacdonald Год назад
WARNING *sarcasm* DETECTED
@phizc
@phizc Год назад
You could have done that in previous versions of .NET too. It's just become a more pleasant coding experience to do so now 😛.
@mrsajjad30
@mrsajjad30 Год назад
For this feature I must say "With greater power comes greater responsibility". Excellent demonstration. Thank you Nick.
@ElmoTheAtheistPuppet
@ElmoTheAtheistPuppet Год назад
"The value is Nick" - You are the value mate appreciate your work
@OlofLagerkvist
@OlofLagerkvist Год назад
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 Год назад
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.
@ristopaasivirta9770
@ristopaasivirta9770 Год назад
Who would win: ten years of SOLID principles vs one unsafe boi?
@woocaschnowak
@woocaschnowak Год назад
With great power comes great responsibility. Don't use your power to change static readonly fields :D
@Demonata1223
@Demonata1223 Год назад
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.
@DennisFazekas
@DennisFazekas Год назад
This seems really handy for unit testing, but I have concerns about using it in other contexts. As someone who writes a lot of infrastructure code, I find it crucial to restrict developers from accessing certain parts of the code.
@Kerbiter
@Kerbiter Год назад
Sure, except when stubborn library devs only design something in the way they see consumers want, not what the consumers really want, and won't change anything and/or it's a lot of hassle to make them change, or it's just simply the way they're building their library.
@parcanapp1193
@parcanapp1193 Год назад
nuke with mandatory .nuke folder immediately came to mind. I use .config for all configuration, and now have an extra folder. I will now go back and check if it is a static readonly as opposed to const by any chance. @@Kerbiter
@ehudv9276
@ehudv9276 Год назад
Yes. haven't thought of that. thats actually a good use case.
@DennisFazekas
@DennisFazekas Год назад
​@@KerbiterI totally get where you're coming from! If the devs aren't providing what's really needed, then there might be a bigger issue going on. I'm all about sharing knowledge and having open code reviews. That way, everyone knows what's going on in the code and if any tweaks are needed, I'm more than happy to make them. I'd rather work together like this than have people go around my code, which could create headaches down the road. 😊
@TheRavenCoder
@TheRavenCoder Год назад
Unit tests are definitely the most obvious use case. I've used reflection before on unit tests and it's a bit messy. I didn't want to make the methods public, because they should not be used directly by the application, but the logic needed to be tested as mistakes could cost the company millions of dollars. This feature would've cleaned that code up a bit.
@PereViader
@PereViader Год назад
Compile time performance is the best part of this ❤
@parlor3115
@parlor3115 Год назад
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 Год назад
"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.
@mindstyler
@mindstyler Год назад
Will we get a dedicated in-depth video about the volatile keyword at some point? It's been 2 years already since you covered it briefly the last time.
@ludwintor4986
@ludwintor4986 Год назад
absolutely agree
@thatcreole9913
@thatcreole9913 Год назад
👀
@tarsala1995
@tarsala1995 Год назад
Ideally with some multithreaded examples
@IronJmo
@IronJmo Год назад
It's funny seeing a comment about this because I just used this recently on a project for the first time.
@renauddanniau676
@renauddanniau676 Год назад
Volatile is not really complex, you should read what MSDN has on it and you will easily understand how to use it :). You need to have a good understanding about how multithreading works and what are L1, L2 and L3 caches.
@Tolg
@Tolg Год назад
This is fantastic! I think it will allow for me to make more things private, and still have them testable. I’ve had so many cases where I couldn’t make something private because I needed to expose to my testing framework.
@filadog
@filadog Год назад
@@jkdmyrs how do you test private async event handlers on UI, say WinForms? This will be handy in such cases when in memory UI testing is required. Faking button clicks and such. In my place we use MVP pattern for UI code extensively and have a custom framework for testing presenters with specflow. It's real nice to work with, you just say User clicks button "Download". And reflection magic calls private event handler for that button in the presenter. Might use this feature in the future instead.
@jangohemmes352
@jangohemmes352 Год назад
The tests are screaming at you that you aren't designing your code and tests right. NEVER test internals. They are internal so that they are free to change without breaking tests
@Tolg
@Tolg Год назад
I know this is a contentious topic and I don't intend to start a, how to correctly write and test your code correctly war, here in Nick's video comments. In general, I do agree with you. You should only need to test your public interfaces. However, even for backend code, sometimes in libraries there is good reason unit test certain methods such as utility methods which may have flexibility extended to them to address future needs or test integration code that is not conducive to easily being mocked out without leaking abstraction. You could abstract out such code, mark things as internal and add InternalsVisibleTo to your library to allow its testability, but I feel that modifying a base library in such a way just to be able to test, is not exactly proper either. So I will certainly experiment with this new capability to help improve my code and my code's testability.
@paulcarlton598
@paulcarlton598 11 месяцев назад
I've dealt with this too, to get around it, I'll create a testing interface for the object only to expose the needed methods through that testing interface only. It's a way to keep the intent of the contract while being able to cast to a testing interface for the unit test suite. This functionality though actually gets rid of that need which I definitely appreciate, because in all honesty I feel like my workaround, although stays clean, is kind of a workaround.
@markhenderson5283
@markhenderson5283 Год назад
My experience with code using refection is it is either doing something really powerful and useful or something stupid. It is usually always the second one.
@anonimzwx
@anonimzwx Год назад
Imo reflection is useful for testing private things or to call generic methods with multiples types.
@mz00956
@mz00956 3 месяца назад
I use reflection in my GPT library. GPT can call "tools" but need them in json format, and then calls them in json format. What I accomplished for my library is that I can just write //static model.addTool(() => MyClass.MyMethod); //instance model.addTool(mc => mc.MyMethod2); And converting them to json as well as finding and invoking them again after getting a json call happens in the background. This is saving so much time. (Though I only accept public methods, didn't even think private ones would work)
@benjaminclehmann
@benjaminclehmann Год назад
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 Год назад
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
@BillyBraga
@BillyBraga Год назад
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 Год назад
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 Год назад
That will be very useful, especially on nuget packages those not maintained anymore.
@noon9548
@noon9548 Год назад
​@@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 Год назад
The first place I will use it is to grab the array under List
@mbenoni7397
@mbenoni7397 Год назад
You can already do that with CollectionsMarshal.AsSpan()
@TheRicherthanyouguy
@TheRicherthanyouguy Год назад
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 месяцев назад
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.
@PeterOeC
@PeterOeC Год назад
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
@IllidanS4
@IllidanS4 Год назад
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.
@DemoBytom
@DemoBytom 11 месяцев назад
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 Год назад
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.
@rreiter
@rreiter Год назад
5:50 Yes, I want to easily access private members that I shouldn't be using, and, oh, 11:00 so much for readonly, ... this will be fun (especially if it is performant, lol). I wish the Law worked like this: "Yes, Officer, I broke this law, but I said a special word when I was doing the bad act, so that makes it ok and it's all good."
@dadcraft9949
@dadcraft9949 Год назад
Did you know that if you cache an open instance delegate instead of the MethodInfo you can get the same performance with "reflection" (actually with a delegate) that you see with the UnsafeAccessor? All you have to do is call CreateDelegate with a type argument that accepts the target type as a parameter, in this case Func. var testInstance = new Example(); var openDelegate = typeof(Example) .GetMethod("Method", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) .CreateDelegate(null); var name = openDelegate(testInstance);
@nickchapsas
@nickchapsas Год назад
I do, and I have made a video on it. It's not quite the same performance and it can't be JITed the same way either plus its usecases are quite more limited, but it's very close
@SimpMcSimpy
@SimpMcSimpy Год назад
That is not the point of this feature. This was added for AoT compilation. Reflection in general doesn't work well with AoT, this is sort of quick patch for such cases.
@dadcraft9949
@dadcraft9949 Год назад
@@SimpMcSimpy yeah I'm not recommending anyone should choose this approach (for anything ever, really). I just think it's worth knowing about if you are stuck with legacy reflection code and need to optimise it. It's odd to me how many performance focussed articles and videos will measure reflection performance without touching on how trivial it is to boost the performance to match a virtual method call in many situations.
@SimpMcSimpy
@SimpMcSimpy Год назад
@@dadcraft9949 You are correct. I saw that in many articles :)
@DynamicalisBlue
@DynamicalisBlue 5 месяцев назад
Thanks for this. I'm using cached reflection for something at the moment. I also thought of creating a delegate for performance purposes, or at least some reference to an actual native method but I couldn't figure out how to do it. I didn't know there was a method called CreateDelegate this entire time.
@bluesillybeard
@bluesillybeard 10 месяцев назад
Surprisingly often I find myself needing to call a method that isn't in the public API of a library. It's usually a method that should be public, but the creator of the library thought otherwise or just accidentally wrote the wrong keyword. Using this will be a lot easier than using reflection, so I consider it a bonus. Plus, I imagine it works with AOT too (since it links at compile time) to make reflection-like things possible for anyone using AOT.
@1dfe-4e68-bd9f
@1dfe-4e68-bd9f Год назад
.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 Год назад
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.
@ja_mcito
@ja_mcito Год назад
Maybe it's just for use in highly optimized libraries
@SimpMcSimpy
@SimpMcSimpy Год назад
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?
@gliaMe
@gliaMe Год назад
Regarding the code mess of the reflection solution, I had an extension method for the reflection calls in a project. Worked for any property of any class.
@SlackoJacko
@SlackoJacko Год назад
Nick's on a mission to one up each .Net 8 video with something having even more terrifying possibilities.
@nickbarton3191
@nickbarton3191 8 дней назад
I saw Zoran Horvat do something like this for field mapping with Entity Framework. It being private makes it clear that it's not part of the model API was his reasoning.
@MikeZadik
@MikeZadik Год назад
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.
@kconfesor
@kconfesor Год назад
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.
@DivingDeveloper
@DivingDeveloper Год назад
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.
@AlFasGD
@AlFasGD Год назад
I got ill just by hearing your voice, get well soon Nick
@nickchapsas
@nickchapsas Год назад
Damn I didn't know people would notice! Thanks ❤
@Noceo
@Noceo Год назад
This is gonna result in some fun code bases to maintain in 3-5 years from now... (I do see a case for debugging, learning and fiddling around with stuff, but never for production code)
@marsgal42
@marsgal42 Год назад
This looks like one of those features where you may only need it once a year. But you'll *really* need it.
@tchpowdog
@tchpowdog Год назад
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.
@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.
@nocturne6320
@nocturne6320 Год назад
This is an amazing feature, only a shame that you haven't included a benchmark for a compiled lambda as well.
@AlwaresHUN
@AlwaresHUN Год назад
Its great till my colleagues don't know about it :D
@hichaeretaqua
@hichaeretaqua Год назад
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...
@TohidAzizi
@TohidAzizi 10 месяцев назад
Nice! it is something that I probably only use in my unit tests!
@peroyhav
@peroyhav Год назад
Have had to access internal methods from external APIs previously, this would have made that experience easier. Looks a lot like calling external APIs in the.net 3.5 days, so its at least consistent with how interop code was written to get access to hardware drivers etc.
@thunderdeer6073
@thunderdeer6073 Год назад
Sometimes you gotta do what you gotta do
@MrDragnil
@MrDragnil Год назад
Could be useful for certain testing situations as well.
@dimitris470
@dimitris470 7 месяцев назад
WoW this is God-sent. I've been writing a state-machine/workflow library kind of thing, and the fastest I managed to access properties etc was with compiled expressions, which still was a lot slower than direct access. Too bad it does not support Generics yet... it would simplify many things
@iam3yal
@iam3yal Год назад
I've read various comments that essentially say that this kind of mechanism defeats the purpose of access modifiers so I hope my explanation is going to help and clarify some of that confusion or misconception, as strange as it might sound to some people access modifiers were never designed as a permission system but as an encapsulation mechanism to control the visibility of different parts of the system not to prevent it, this concept exists in programming mainly for maintainability and usability, e.g., the engine of a car is hidden within the engine compartment whereas the hood is restricted. Point is this mechanism of .NET 8 to access members (and soon types) changes nothing people that wanted/needed to access your code before could always do it through reflection or more hacky alternatives depends on the language/platform so if people are using access modifiers to restrict developers from code that is actually sensitive data then they are using the wrong tool for the job.
@modernkennnern
@modernkennnern Год назад
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 Год назад
I tried. You can't set its value since its marked as a JIT intrinsict
@modernkennnern
@modernkennnern Год назад
@@nickchapsas that's great
@Neonalig
@Neonalig Год назад
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 Год назад
...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 5 месяцев назад
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.
@warny1978
@warny1978 Год назад
I see a use case. I used that use case many times. I have a method that I need to unit test. I also do not want developpers to directly use that method so I make it private or protected. This allows to do that without complicated code. Another Use Case: I have created an abstract class that keeps track of field changes. This is done with backing field not visible to the end class. This allows me to access these hidden fields without permitting a developper to use it directly.
@Dimencia
@Dimencia Год назад
This isn't the worst thing you can do in C#; most of a dev's job is finding that balance between terribleness and efficiency. Always nice to have more tools in the kit
@ForeverZer0
@ForeverZer0 Год назад
I agree. More power is never a bad thing, so long as their is sufficient barriers in place from doing it accidentally. As long as the user must do "unsafe" (I hate this term) explicitly, there is nothing wrong with a language supporting it.
@memes_gbc674
@memes_gbc674 Год назад
a wise man named terry davis has mentioned this many times
@ForeverZer0
@ForeverZer0 Год назад
@@memes_gbc674 TempleOS was glorious: an entire OS where everything occurred in kernel-space. The "muh safety" cult would lose their minds if they knew.
@aj.arunkumar
@aj.arunkumar Год назад
1 year from now nick will go like "now Im become death, the destroyer of clean codes"
@sergeynosov8180
@sergeynosov8180 Год назад
Is this a good use case for private members that are made public for no other reason but to make unit testing easier?
@osono-io
@osono-io Год назад
I came to the comments to post this same use case. This will indeed be useful.
@SylvanFeanturi
@SylvanFeanturi Год назад
No. The correct solution is to only test public API.
@JohnAndrews_nz
@JohnAndrews_nz 6 месяцев назад
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.
@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 Год назад
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.
@99aabbccddeeff
@99aabbccddeeff Год назад
It's really helpful feature in some rare cases. Thanks for the sharing.
@IceQub3
@IceQub3 Год назад
Thanks I will use it in all my code now
@Shynobyn
@Shynobyn Год назад
I kinda prefer C++ approach to this, defining friend classes that can just access the private implementation.
@proosee
@proosee Год назад
Don't you need to modify base class to be able to to define friend classes? I'm asking because the only use case for accessing private methods/fields I've seen is that you have some legacy dependency that you cannot change, but you need to do something that designers didn't anticipate. Thus, modifying the base class is not an option.
@duramirez
@duramirez Год назад
Gandalf power I see 👀
@Shynobyn
@Shynobyn Год назад
@@proosee Yes it's a different philosophy indeed. Personally I've felt this could be useful in cases where I have a class and a builder class and there's some methods I wouldn't want to expose but the builder needs.
@proosee
@proosee Год назад
@@Shynobyn I'm sorry, I think we are talking about two different subjects. Friend classes must to know each other, thus, you must modify both implementations, in C# we use reflection in mostly two cases: - we want to make something generic, e.g. a serializer - we want to access something we weren't suppose to - e.g. we have legacy library we can't rid off easily and we can't modify it either. Proposed solution is elegant and performant way to not to use reflection in second case.
@V123098456
@V123098456 Год назад
Very interesting but something I would need a very good reason to use.
@xslashsdas
@xslashsdas Год назад
I dunno, since I've never seen a case where I had to actually do this and not be okay with lower performance maybe my opinion is irrelevant. But, making it easier and more powerful is like removing the safety from a gun because it's quicker to shoot.
@kelton5020
@kelton5020 Год назад
I dig it. I think this makes a lot of sense for them to iterate and improve all aspects of the ecosystem, instead of just neglecting the unsightly parts.
@JorneDeSmedt
@JorneDeSmedt 11 месяцев назад
Seems useful for unit testing your private methods.
@PeteSauerbier
@PeteSauerbier Год назад
Can this be done with extensions as well?
@innerbytes
@innerbytes Год назад
I see it very usefull for testing in some scenarios.
@jacquesdemolay2699
@jacquesdemolay2699 Год назад
if you are not supposed to use something - it makes sense to make it more difficult to do. but to make it easier is an invitation to use. is this reasonable ?
@danielrdm
@danielrdm Год назад
Sometimes you need to access private stuff for whatever reason. Thanks for sharing.
@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.
@Marius-ir1qn
@Marius-ir1qn Год назад
What happened ? Spell it out boy.
@ehudv9276
@ehudv9276 Год назад
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.
@trevorprice2490
@trevorprice2490 11 месяцев назад
Thinking ahead to use cases I might encounter, I'd probably add an "Unsafe" suffix to all my "Caller" method names just to add a reminder to any users about what's potentially happening behind the code
@jongeduard
@jongeduard Год назад
I would say it opens more ways of unit testing, and especially performance testing (since it no longer has to be slower than public calls) of your own projects. Generally I also really like the better philosophy that in the end a compiler should not actually limit you to do things, but can give you full control if you really demand so. In the end it's up to YOU as a developer to make good coding decisions. A compiler should not be needlessly childish, but help you by making make guidelines clear. By disabling private access with the normal way of calling, the message is already clear, you should normally not want to do it, since it defeats purpose.
@Youcef8830
@Youcef8830 Год назад
my thoughts exactly
@The_Genezis
@The_Genezis Год назад
every time he said "the name is" I filled "Primogean" in my head. Please help
@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.
@darthruneis
@darthruneis Год назад
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).
@mclifeleader
@mclifeleader Год назад
As a developer and an engineering manager, I can say that as helpful as this maybe it wreaks of code smell!
@skeggs
@skeggs Год назад
Love the captioning of your opening line at 0:00 "hello everybody I'm naked in this video.." 😇
@Gavin556
@Gavin556 8 месяцев назад
this is what you need for writing unit test when you don't want to expose everything as public
@bachph
@bachph Год назад
With great power comes great responsibility! 🕷
@leowong9885
@leowong9885 4 месяца назад
Thanks for introducing this new feature. I am wondering what is the motivation behind it. If authors of classes want people to have access to protected/private methods/fields, would they have not marked the functions or fields public instead?
@the-niker
@the-niker Год назад
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.
@元始天尊-b7k
@元始天尊-b7k Год назад
This is Assembly Publicizer which has been available for a long time in modding community
@fredericbrown8871
@fredericbrown8871 Год назад
I think it can help write more robust and cleaner code when you have to use reflection anyway (assuming type safety is enforced for the extern methods of the caller class). However I would be warry of accessing, let alone setting (especially if read only), private members. I guess there might be edge cases I'm not thinking about that justify it, but unless it's for the purpose of diagnostic it feels antithetical to encapsulation and the safety it provides and looks like looking for trouble to me.
@bftanase
@bftanase Год назад
The automatic youtube captioning is hilarious: "Hello everybody, I'm naked in this video ... "
@tanglesites
@tanglesites Год назад
This breaks encapsulation. What use cases does this have?
@BGroothedde
@BGroothedde Год назад
Nice, another footgun! It's almost C++ now :D
@SylvanFeanturi
@SylvanFeanturi Год назад
I think that the only thing that's missing is pointer arithmetic?
@DynamicalisBlue
@DynamicalisBlue 5 месяцев назад
I wish. I'm currently on a C++ and a C# project. Whenever I'm on the C++ project, I miss reflection. Whenever I'm on the C# project, I miss being able to do what I want. (The thing I hate the most about C#, is not being able to treat a nullable as a bool. Let me do `if (someNullable)` Please!
@antred11
@antred11 Месяц назад
@@SylvanFeanturi To be fair, pointer arithmetic is generally unnecessary in truly modern C++ (I'm not talking 90s-style C++ here).
@diadetediotedio6918
@diadetediotedio6918 Год назад
11:55 Yeah, but you can do it with unsafe (in fact, something very much more unsafer than to change a readonly field, but to change the string contents itself) Reflection was not able to do it before? I have an impression that it could
@nickchapsas
@nickchapsas Год назад
You can do anything with unsafe but no, you couldn't do it with reflection
@diadetediotedio6918
@diadetediotedio6918 Год назад
​@@nickchapsas Hmmm, thanks. That probably was a mistake or false memory of my part
@vyrp
@vyrp Год назад
After some quick tests, I see that trying to modify a static readonly field in .NET 7 throws FieldAccessException, but works fine in .NET Framework 4.8
@aathifmahir
@aathifmahir Год назад
Great power comes with great responsibility, hope devs don't start doing stupid things with this feature
@samysammour9983
@samysammour9983 Год назад
They will! Believe me
@aathifmahir
@aathifmahir Год назад
@@samysammour9983 that's what my concern as well
@user-nq8ln7ps7x
@user-nq8ln7ps7x Год назад
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.
@MayronWoW
@MayronWoW Год назад
Unlimited POWER!!
@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.
@SylvanFeanturi
@SylvanFeanturi Год назад
So first they added multi-inheritance, and now they removed encapsulation... Great, just great. Can we just rebrand to JavaScript# and be done with it? This won't simplify bad code - this IS a bad code.
@jeffcarey3045
@jeffcarey3045 Год назад
0:00 "Hello everybody, I'm naked in this video" - RU-vid Captions, 2023
@jacquesdemolay2699
@jacquesdemolay2699 Год назад
Could you give examples of when we MIGHT need to access a private method ?
@markmidwest7092
@markmidwest7092 Год назад
Unit tests
@arjix8738
@arjix8738 Год назад
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!)
@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.
@MichaelMortensen
@MichaelMortensen 10 месяцев назад
Wonderful insights, thanks!
@bayoucaneboy9332
@bayoucaneboy9332 Год назад
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.
@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?
@JustArion
@JustArion Год назад
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.
@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.
@RobinJohannesson
@RobinJohannesson Год назад
That is awesome! But how does it work underneath? How do UnsafeAccessor attribute know what type I am using? And what happens if I have two instances of the same class, but with different values? And what happens if there is multiple functions with the same name?
@TheMonk72
@TheMonk72 Год назад
My guess is that the "extern" keyword is doing all the heavy lifting here. In previous versions of the language it creates code to call a library method. Looks like they did something similar here except the compiler just inserts code to call/reference things you normally wouldn't have access to.
@GumbootMan
@GumbootMan Год назад
@@TheMonk72 Good guess, but nope, the compiler is not involved. Rather, this feature is implemented in the JIT -- it sees the [UnsafeAccessor] attribute and generates the appropriate IL to call the method or get a reference to the field. If the target method/field is not found, then it generates code to throw an exception instead. (This actually explains why getting the name wrong is not a compiler error -- can't trigger a compiler error if the compiler is not involved!)
@TheSlimshader
@TheSlimshader Год назад
This is a great tool in combination with source generators
Далее
Await Async Tasks Are Getting Awesome in .NET 9!
9:24
The New Way of Parsing ANY Type in .NET
13:03
Просмотров 69 тыс.
Living life on the edge 😳 #wrc
00:17
Просмотров 7 млн
.NET and C# are in trouble. Here is what I'd do.
10:57
Stop Using FirstOrDefault in .NET! | Code Cop #021
12:54
Don't Use Polly in .NET Directly. Use this instead!
14:58
Swagger is Going Away in .NET 9!
10:48
Просмотров 96 тыс.
Being Competent With Coding Is More Fun
11:13
Просмотров 89 тыс.
Settling the Biggest Await Async Debate in .NET
14:47
Просмотров 144 тыс.
The New Best Way To Search for Values in .NET 8
11:05
LINQ's INSANE Improvements in .NET 9
11:26
Просмотров 52 тыс.