How C# 10 “fixed” string interpolation

  Рет қаралды 76,070

Nick Chapsas

Nick Chapsas

Күн бұрын

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 show you how the introduction of InterpolatedStringHandlers in C# 10 and .NET 6 completely change the way we think about them. Not only is string interpolation significantly more efficient now when it comes to speed and memory, but you can also create your own InterpolatedStringHandlers to completely eliminate allocations in some cases.
Timestamps
Intro - 0:00
The problem - 0:38
How Microsoft fixed it - 3:00
How you can build your own - 8:17
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 #performance

Пікірлер: 109
@TheLeftExitNET
@TheLeftExitNET 2 жыл бұрын
I think it's important to point out that .NET 6 interpolated strings are now compiled to that new `ref struct` type that is implicitly cast to string. Realizing this made understanding this topic much easier for me. Other than that, thanks for the explanation!
@CharlesBurnsPrime
@CharlesBurnsPrime 2 жыл бұрын
I have long saved development videos, but only the very best -- videos with content that is useful, interesting, high-quality, and not trivially found with a web search. I find that list has grown by nearly every video I have seen on your channel. Your to-the-point, in-depth, not-afraid-to-be-technical format and your passionate approach to real world challenges and solutions, acknowledging how awesome C# is but without the immature wall of isolationism developers often build around their favorite solutions, is prime-grade KZbin content.
@col_rod
@col_rod 2 жыл бұрын
It's great to see how your voice and facials expressions change when you are showing something as cool as this. It makes feel the one listening to be excited about what you are showing too. Thanks for showing this level of enjoyment and keep up the good work.
@evgeny6692
@evgeny6692 2 жыл бұрын
As clear as it ever could be! Great job, thank you!
@Appl_Jax
@Appl_Jax Жыл бұрын
Whoa, I haven't been following closely the more recent additions to C# since 10 but man... it's turning out to be one of my favorite updates. Just discovered InterpolatedStringHandlers (and your video) today but the mention of the CallerArgumentExpression is another jawdropping addition to me. That actually solves a problem I had for a feature I needed to implement. Looks like I'll need to go back and look through all the changes to see what else I'm missing.
@xavier.xiques
@xavier.xiques 2 жыл бұрын
Thanks again for your videos, Nick! You help me a lot.
@dannystaten5701
@dannystaten5701 2 жыл бұрын
I'm curious if entity framework's latest iterations have applied this kind of optimization considering the massive amount of string building or interpolating involved in creating sql statements.
@ChristofferLund
@ChristofferLund 2 жыл бұрын
Thanks for explaining. Great that they fixed it!
@BrokoIis
@BrokoIis 2 жыл бұрын
What I don't like about features like these is that they have no contract on declarations/definitions. They are not implementing an interface or extending a class, or using some sort of other way to ensure, that you're implementing such features correctly. The same is with async/await and GetAwaiter/Awaiter class, or the Deconstruct method. It's basically "convetion-based". Other than that, I love language features, which compile into something more, but still let you customize what it compiles into. It makes the code clean, more readable, but still optimized. I believe it's also possible to customize the async method builder, would love a video about that. Thanks for great content!
@briankarcher8338
@briankarcher8338 2 жыл бұрын
This is a good point and unfortunately Microsoft has a good counter argument. The reason .NET doesn't use many interfaces for their classes is for backwards compatibility. They're afraid an interface change will break millions of lines of code that people have written and they weren't able to come up a good alternative solution at the time.
@saniel2748
@saniel2748 2 жыл бұрын
@@briankarcher8338 Isn't this what default implementation for
@krccmsitp2884
@krccmsitp2884 2 жыл бұрын
This is some really insane (read: awesome) stuff. Thanks for showing.
@thanasakis61
@thanasakis61 2 жыл бұрын
Να ΄σαι καλά ρε Νικόλα για την γνώση που προσφέρεις!!!!!
@IceQub3
@IceQub3 2 жыл бұрын
thanks for the great video!
@Palladin007
@Palladin007 2 жыл бұрын
I have an implementation for logging ^^. You can pass a normal interpolated string to a log method and it will generate a state to create the message or provide all values for structured logging. The performance is not as good as generated logging (you explained it in your last video) and for a "real world" software I would still use the generated logging, but it's cool :D And it would be possible to create SQL statements in code with string interpolation and nobody can "forget" the parameters because the handler adds them automatically.
@brandonsquires9709
@brandonsquires9709 2 жыл бұрын
Have you done a video on IO pipelines and/or channels? I had to use those recently and definitely would like to learn more about them. Thanks for the great vids!
@fieryblast
@fieryblast 2 жыл бұрын
I love this, can see how this would be very beneficial for logging conditionally and enabling logging middlewares to determine if it should log or not instead of having to wrap the code in extensions etc
@nickchapsas
@nickchapsas 2 жыл бұрын
You shouldn’t use string interpolation for logging. You’re going to lose the structured logging parameters and also when you end up logging for an active log level, it’s gonna use significantly more memory even with this efficient approach.
@khellang
@khellang 2 жыл бұрын
​@@nickchapsas Interpolated string handlers were actually designed with logging as one of the primary use cases. Adding CallerArgumentExpression to your AppendFormatted methods, you can preserve structured logging names. I have a (somewhat) working prototype for Serilog using this, but Serilog makes it a bit more complicated because of custom syntax for structure capturing operators (stringification and destructuring), but it's doable. In terms of memory, you can declare it as a ref struct (like DefaulteInterpolatedStringHandler) and basically avoid all (heap) allocations when logging is turned off :)
@fieryblast
@fieryblast 2 жыл бұрын
@@nickchapsas I agree completely. I was referring to whether we log the whole string or just part of it for non structured logging where we log something regardless just amount/detail. Aldo where do you hear about these features?
@nickchapsas
@nickchapsas 2 жыл бұрын
@@khellang The problem with CallerArgumentExpression is that is can capture ANY expression, so if in the place of a parameter you place a "DataTime.Now.ToString()" then good luck capturing that in structured logging. It's doable if absolutely everyone that's gonna touch the project is on the same page. The other problem with it is that even if you are to have a conditional shouldAppend check, and then instantiate a handler internally which is still a ref struct, you still actually allocate more memory than you need when logging is actually turned on. You can test that with the Debug.Assert example. When it doesn't fail it doesn't allocate any memory but when it does fail, then the AssertInterpolatedStringHandler ends up allocating more than before. You just can't beat source genned LoggerMessage.Define in performance.
@fatemehmaleki9780
@fatemehmaleki9780 2 жыл бұрын
Prefect
@davidheale6435
@davidheale6435 2 жыл бұрын
Well, now I wonder if you were to combine what you've shown us here with your logging optimization, would it actually be faster to use string interpolation? Either way, thanks for the video!
@nickchapsas
@nickchapsas 2 жыл бұрын
You technically can, I was actually planning to show that as an example but the thing is that you don’t wanna do that because you wanna for structured logging to capture the variable consistently so in logging it’s still a bad practice
@10HW
@10HW 2 жыл бұрын
The only thing I know how to code is a window with an exit function in Visual Basic on Windows XP, this video was entertaining yet absolute gibberish.
@fr3ddyfr3sh
@fr3ddyfr3sh 2 жыл бұрын
Damn, you are pretty knowledgeable. Only be careful with microbenchmarks, loop alignment is a big thing in this scenarios. Especially when comparing .net 5 (basically no loop alignment) and 6 (optimized loop alignment). In .net 5, changing the order of methods in the class can lead to different benchmark results.
@MyGreenpotato
@MyGreenpotato 2 жыл бұрын
Άψογος!
@petrusion2827
@petrusion2827 2 жыл бұрын
I think you should also show your viewers the ISpanFormattable interface and the memory implications of implementing it in classes and structs that are used in string interpolation
@alphaios7763
@alphaios7763 2 жыл бұрын
Hi. Great video as always! I wanted to ask you about a problem specific to programmers, but not code :) What chair are you using? If I'm not mistaken, the logo looks like Secretlab. Is it good for long day's work? I am considering some ergonomic chairs, but they tend to be very expensive and I don't think I should rush with such a big investment. I want to use something that will keep me healthy for years to come and am wondering how it's been treating you so far. Thank you for all the videos. I really enjoy learning about topics I never encounter on my job, really is a breathe of fresh air! Keep up the great work!
@nickchapsas
@nickchapsas 2 жыл бұрын
It’s as good as gaming chairs get but to be honest, a used Aeron would probably be a better investment. Im very happy with it, especially with their new softer seat, but I would try before I buy
@T___Brown
@T___Brown 2 жыл бұрын
Doesnt this completely change your recent logging video? Amazing stuff. Thanks for sharing
@nickchapsas
@nickchapsas 2 жыл бұрын
No, the recent video is still more efficient than this because you don't allocate anything again no matter the log level.
@gardenhouseNemurin
@gardenhouseNemurin 2 жыл бұрын
Quick question, is there any particular reason not to use a `Func` and only call it if the condition passes? Couldn't we save as much memory this way?
@nickchapsas
@nickchapsas 2 жыл бұрын
You will end up allocating more memory when you actually log so even though it is an option, it is not the most efficient one. It is also prone to closures that can lead to even more memory problems
@antonmartyniuk
@antonmartyniuk 2 жыл бұрын
Great video. Nick, a quick question about memory efficiency: are you using transient/scoped or singleton services and repositories?
@nickchapsas
@nickchapsas 2 жыл бұрын
It depends on the backing library
@antonmartyniuk
@antonmartyniuk 2 жыл бұрын
@@nickchapsas do you agree that services should be scoped unless they need a state insde? The author of MediatR says that we need to do so and the extra object allocation is miserable
@nickchapsas
@nickchapsas 2 жыл бұрын
@@antonmartyniuk It really, heavily depends on your dependencies. I don't use MediatR in high-perf situations anyway so it doesn't matter.
@evtimstefanov5441
@evtimstefanov5441 2 жыл бұрын
Is there a similar extension for VS that shows what we see on 3:11
@modernkennnern
@modernkennnern 2 жыл бұрын
Does this affect String.Format in any way, or is String.Format (even more of a) legacy feature?
@petrusion2827
@petrusion2827 2 жыл бұрын
AFAIK: string.Format is the same as it was before C#10. string.Format has already been making use of the ISpanFormattable interface before it was made public.
@Ajay-km8br
@Ajay-km8br 2 жыл бұрын
Nick, After watching your channel for so long, the quality of others just does not cut it for me. Can you make a series on Golang? We all win. I’ll send you a six pack of beer.
@asdasdasdasd-yd8ht
@asdasdasdasd-yd8ht 2 жыл бұрын
Cool. Hey Nick, can you help me understand how you saved memory? Okay you did that for saving the space of string provided in method... but what about the extra space you allocated for your extra class?
@BambeH
@BambeH 2 жыл бұрын
The EnsureInterpolatedHandler is a struct which only wraps the default C# handler struct. This wrapper only added behavior, not data, so no additional memory should be needed due to them being structs instead of classes (so no pointers to other heap-allocated objects). Please do correct me if I'm wrong though, would really love to dive deeper into this C# topic :D
@nickchapsas
@nickchapsas 2 жыл бұрын
It's not about EnsureInterpolatedHandler being a ref struct but also about the AppendFormatted method using a generic which will prevent the boxing that happen with the string.Format method
@jerry9548
@jerry9548 2 жыл бұрын
I feel like a total noob when I watch your videos. I mean I'm stilla student, but I would like to get to your lvl some day :) Do you have any beginner to intermediate to pro courses for C# and .Net planned?
@emoney9979
@emoney9979 2 жыл бұрын
Hi Nick, I admire your work a lot. What about Q&A at 100k subs? :D you could make a post with question and choose most liked. Cheers from Poland!
@jsfelipearaujo
@jsfelipearaujo 2 жыл бұрын
Hi Nick, first of all excellent video, congratulations! I’ve an off-topic request: I was recently developing a specific service and I came across that the class in question was getting a lot of dependency injections. After searching a bit I saw that the Facade design pattern could somehow help me, but some people say that it violates some SOLID principles. Could you make a video about this design pattern? Thank you so much in advance.
@gustavnilsson6597
@gustavnilsson6597 2 жыл бұрын
RawCoding does alot of design pattern videos and has one about Facade kzbin.info/www/bejne/rqvToWiVltBrfsk&ab_channel=RawCoding
@computer9764
@computer9764 2 жыл бұрын
Those method forwards are a great candidate for expression body over statement body 👀
@nickchapsas
@nickchapsas 2 жыл бұрын
Yeap, I use statement body because of the folding. Expression body will get out of screen and be hard to show in the video, but you’re right, you would use expression body there
@jamienordmeyer4345
@jamienordmeyer4345 2 жыл бұрын
Huh... I USED to think that I was a C#/.NET expert... LOL
@julienlefevre1661
@julienlefevre1661 2 жыл бұрын
Hello Nick, nice video again. Can you explain why private DefaultInterpolatedStringHandler should not be readonly? If it is as suggests Visual studio then ToString returns an empty string. 🙂 Thanks !
@Appl_Jax
@Appl_Jax Жыл бұрын
In the optimized version of the method when the condition is successful, he removed the reference to the default handler as it wasn't needed so had to be able to change that. Though it could have easily be rewritten in such a way that it could be readonly by conditionally setting it in the ctor.
@Rynas
@Rynas 2 жыл бұрын
Though all that is saiud in the video here is technically correct, I think it is a very complicated and not very transparent way to achive the goal. I normally use a Func argument in cases, where I want/need to think about performance - run time here. I have inserted a short demo to present my case below (though KZbin chat formatting isn't good for that). The time improvement in this case is above 99%, though I have not benchmarked memory consumption, so I have no idea if there is a difference here. using System; using System.Diagnostics; namespace StringConcatPerformance { class Program { /// /// Standard way to call method with string argument /// /// If false the message argument will not be used at all /// Represents some string, that it has taken some time to build public static void NormalMethod(bool showMessage, string message) { if (showMessage) Console.WriteLine(message); } /// /// Alternative way to call method with string-returning function argument /// /// If false the messageFunc argument will not be used at all /// A function, that, but only if showMessage argument is true, build and return a string value when called public static void FuncedMethod(bool showMessage, Func messageFunc) { if (showMessage) Console.WriteLine(messageFunc.Invoke()); } static void Main(string[] args) { // Example of how to call "the old way" and as Func-argument NormalMethod(false, $"This string is created at {DateTime.Now:yyyyMMDD HHmmss.fff}"); FuncedMethod(false, () => $"This string is created at {DateTime.Now:yyyyMMDD HHmmss.fff}"); // Simple Stopwatch times benchmark test. Call both methods a lot of times but never actually use the Message/MessageFunc arguments var calls = 100000; var watch = new Stopwatch(); watch.Reset(); watch.Start(); for (var i = 0; i < calls; i++) NormalMethod(false, $"{i}'th call, {DateTime.Now:yyyyMMDD HHmmss.fff}"); watch.Stop(); var normal = watch.ElapsedMilliseconds; watch.Reset(); watch.Start(); for (var i = 0; i < calls; i++) FuncedMethod(false, () => $"{i}'th call, {DateTime.Now:yyyyMMDD HHmmss.fff}"); watch.Stop(); var funced = watch.ElapsedMilliseconds; Console.WriteLine(@$"{calls} calls Normal: {normal} msec, Funced: {funced} msec"); Console.WriteLine(@$"Difference: {(100 - 100.0 * funced/normal):N02}% saved with FuncedMethod"); } } }
@nickchapsas
@nickchapsas 2 жыл бұрын
Firstly, you should be using BenchmarkDotnet if you wanna get any reliable benchmark results. The problem with your code is the closures you create. It's not just about the speed but also, or even more, about the memory.
@danielbocelli
@danielbocelli 2 жыл бұрын
I’m new to C# and this level of programming. Where do you recommend I start so that I can understand what you mean when you refer to heap vs stack, references, class vs struct, etc. ?
@nickchapsas
@nickchapsas 2 жыл бұрын
Check this video out: kzbin.info/www/bejne/oICxhHyegriHb6c
@danielbocelli
@danielbocelli 2 жыл бұрын
@Brian Williams I mean that it’s never been a concern for me at my level of experience. You couldn’t deduce that or are you being pedantic?
@temp50
@temp50 2 жыл бұрын
@Brian Williams uhm, functional form of programming for example? :) I mean when were you worry about these things in a typescript or a python code last time? :D
@MacroEnabled
@MacroEnabled 2 жыл бұрын
@Brian Williams Program correctness is more important than program performance in most cases
@Cerebrate78
@Cerebrate78 2 жыл бұрын
If I noticed correctly, the code that you’ve written in the EnsureInterpolatedStringHandler constructor was actually inlined into the caller. If so, does it make sense to make this type “ref struct” as it is not instantiated anyway?
@nickchapsas
@nickchapsas 2 жыл бұрын
It wasn't inlined. The compiler took that and instantiated the ref struct appropriately, so it is instantiated.
@Pezsmapatkany
@Pezsmapatkany 2 жыл бұрын
The "ref struct" guards against boxing the value into the heap. So, it is just a safeguard to ensure that the code in the handler will not box it, to ensure that no unwanted allocations will occur, so yes it makes sense to use a "ref struct".
@Myuuiii
@Myuuiii 2 жыл бұрын
YEEEEEEE
@AlanDarkworld
@AlanDarkworld 2 жыл бұрын
That seems like a lot of machinery to inline an if-statement... Kotlin has inline functions which inline lambda arguments as well. So: require(mybool){ "Failed!" } ... will accomplish the same as the message handler in C#. However, what really is nice in C# are the attributes to fetch the caller class name, caller method name and caller parameter expression. Simple and neat, I wish Kotlin had that.
@nickchapsas
@nickchapsas 2 жыл бұрын
It's more than just inlining the if statement. You can also write custom handling for each type, for example in the case of string interpolcating a sql query. It can do way more things than this very basic example. I do like Kotlin's approach this this problem though. It just doesn't read as nice.
@pablocom
@pablocom 2 жыл бұрын
Wow
@neociber24
@neociber24 2 жыл бұрын
That's a lot of black magic and long names. I understand that ref struct can have interfaces but will be great to be able to have actual types.
@evarlast
@evarlast 2 жыл бұрын
It seems like string.Concat() could be similarly optimized to prevent the boxing by a bunch of generic overloads. Why hasn't this been done? Has it been proposed and rejected?
@FredricSilberberg
@FredricSilberberg 2 жыл бұрын
You have to balance that memory against the explosion of generic specialization the JIT will need to do to have all the versions of `string.Concat` that you'll end up using. Just given 3 arguments with different types, there are 3^2 = 9 ways of ordering those arguments, and there are way, way more than 3 types in any given .NET program. You'd save memory with boxing, but end up losing it all to the JIT for different method compilations anyway.
@IIIIIIIIIIIllllllIIIIIIIIIII
@IIIIIIIIIIIllllllIIIIIIIIIII 2 жыл бұрын
Legit
@1992jamo
@1992jamo 2 жыл бұрын
I don't understand why the .net compiler doesn't just optimise all of the methods to the same code under the hood. Would it cause breaking changing if they did that?
@FredricSilberberg
@FredricSilberberg 2 жыл бұрын
Not sure what you mean. I _think_ you mean why don't we call DefaultInterpolatedStringHandler for all cases? If so, then that's not an optimization, you're loosing perf.
@1992jamo
@1992jamo 2 жыл бұрын
@@FredricSilberberg Yes that's what I meant. It seems that when the compiler decides to use DefaultInterpolatedStringHandler, it's a lot faster (because it doesn't need to box simple value types?) So why does the compiler not use DefaultInterpolatedStringHandler for all string Interpolation
@FredricSilberberg
@FredricSilberberg 2 жыл бұрын
@@1992jamo because that's not faster for all cases. If you have 3 or less strings, it's faster to call string.Concat.
@lollo4711
@lollo4711 2 жыл бұрын
Do the Benchmarks also measure the time GC needs to clean up??? While GC is cleaning up, all TASKs get on HOLD.
@nickchapsas
@nickchapsas 2 жыл бұрын
It does. It measures it as GC time in all generations
@matron_gaming
@matron_gaming 2 жыл бұрын
How can We use faster string interpolations when logging?
@nickchapsas
@nickchapsas 2 жыл бұрын
You shouldn’t use string interpolation when logging. You should do structured logging instead. It doesn’t allocate any memory with source generators or the delegate approach
@nickchapsas
@nickchapsas 2 жыл бұрын
@@fabolt But you shouldn't because you are losing the structured logging parameters
@nickchapsas
@nickchapsas 2 жыл бұрын
@@fabolt In my experience, they are required in most scenarios.
@adamolesiak3295
@adamolesiak3295 2 жыл бұрын
This code does however evaluate all the expressions in the message passed in. For example if you do: static bool flag = true; EnsureThan.IsTrue(1==1, $"blabla {() =>{ flag = false; return "flag was set to false."; }}); Assert.IsTrue(flag); Then this test would actually fail. I was playing around with it a little and I was able to get this test to work with something like: public void IsTrue(bool condition, [InterpolatedStringHandlerArgument("", "condition")] InterpolatedStringHandlerPositiveChecks handler) This has the sad downside of not working with static functions, so I had to use a singleton there.
@FredricSilberberg
@FredricSilberberg 2 жыл бұрын
This is not correct. If the `out` parameter in the constructor is false after construction, no part of the interpolated string handler will be evaluated.
@farsidesc4044
@farsidesc4044 2 жыл бұрын
Sucks about the audio line static. Broken cable?
@nickchapsas
@nickchapsas 2 жыл бұрын
I noticed it in the video I recorded yesterday while I was editing. I will be investigating what causes it today.
@nickchapsas
@nickchapsas 2 жыл бұрын
Looks like removing the CloudLifter from the setup clears the sound
@farsidesc4044
@farsidesc4044 2 жыл бұрын
@@nickchapsas For what it's worth, depending on your setup, you can throw a noise-gate on your recording software to "cheaply" mitigate issues like this.
@farsidesc4044
@farsidesc4044 2 жыл бұрын
@@nickchapsas Don't rule out a bad cable yet. Glad you found the link in the chain though!
@nickchapsas
@nickchapsas 2 жыл бұрын
@@farsidesc4044 Ok so there was actually a noise gate and it was making it less noticable when I was talking. I added the CloudLifter again into the mix and I am getting clean sound so it was probably a loose XLR connection.
@kevinbtube
@kevinbtube 2 жыл бұрын
My brain hurts
@LucasRibeiro-lx8ve
@LucasRibeiro-lx8ve 2 жыл бұрын
any plans to make a giveway of your courses in a near future? :-)
@nickchapsas
@nickchapsas 2 жыл бұрын
No plans for a giveaway no
@shaihulud4515
@shaihulud4515 2 жыл бұрын
I see that guitar in the background, and am afraid you might be as good playing the guitar as you are with coding ;-)
@michaelsniknejs6326
@michaelsniknejs6326 2 жыл бұрын
Hey great video, your English is really good. Just a couple of tips, you always speak fast and not very clearly at the start of your videos and it's hard to know what you're saying because of the Greek accent (but the rest of the video is fine). In this video @10:25 you pronounce "Exception" as "Expression". Your videos are great and this isn't meant as an insult at all, just something to help you improve.
@nickchapsas
@nickchapsas 2 жыл бұрын
Hey thanks! The fast intro is a bit of a meme at this point which is why I’m not slowing it down. In regards to the expression thing, I tend to read words and numbers wrong. Sometimes then number will be 430 and I will say 43 for no reason and it happens with words as well. I usually catch it in edit but I don’t wanna ADR it so I usually just add a text annotation in the video
@BiiraHD
@BiiraHD 2 жыл бұрын
tl;dr - They made the compilation more complex but fixed the running code
@typingcat
@typingcat 2 жыл бұрын
Still annoying that I have to $ before the string to use it. I guess that is for the backward compatibility with the old source code, but when a language gets decades old like Java or C#, I think maybe at some point it needs to give up that compatibility for the greater good. Those who still have old source code could use set some sort of compiler option to compile it in the old way, or use some sort of automated tool to "upgrade" the code to a newer syntax.
@xdelph
@xdelph 2 жыл бұрын
i'm lost
@giladfreidkin4369
@giladfreidkin4369 2 жыл бұрын
Wish that declaration of custom InterpolatedStringHandler would've been inherited from a base class instead of using attribute and compiler magic.
@nickchapsas
@nickchapsas 2 жыл бұрын
Yeah or an interface, it is a bit tricky as it
@remcoros
@remcoros 2 жыл бұрын
@@nickchapsas An interface cannot force a constructor signature. And a base class won't work, since the base class has to be part of the BCL. And this is a compiler (roslyn) trick wich is applied before having access to any of the BCL classes. Same goes for example if you want to use IAsyncDisposable on a target framework which does not have that interface. You can grab it from a nuget package, or define that interface in your own project. Since it's compiler magic, this still works on older frameworks. At least, I 'think' that's the reason :)
@FredricSilberberg
@FredricSilberberg 2 жыл бұрын
@@remcoros We wanted DefaultInterpolatedStringHandler to be a ref struct, which precludes any interface or base type implementation.
@twiksify
@twiksify 2 жыл бұрын
It's a shame that struct cannot be inherited.
@ViktorFerenczi
@ViktorFerenczi 2 жыл бұрын
C# gets way overcomplicated as time goes on...
@caractacustube
@caractacustube 2 жыл бұрын
Anders Hejlsberg is choking on his coffee. Strongly disagree with this kind o contrivedf compiler level kludge.
@FredricSilberberg
@FredricSilberberg 2 жыл бұрын
Anders was in the design review.
Stop using String Interpolation when Logging in .NET
17:30
Nick Chapsas
Рет қаралды 83 М.
How slow is MediatR really?
15:51
Nick Chapsas
Рет қаралды 59 М.
1❤️#thankyou #shorts
00:21
あみか部
Рет қаралды 68 МЛН
Заметили?
00:11
Double Bubble
Рет қаралды 3,5 МЛН
Coding Shorts: For The Record - Why You Should Use (Records in C#)
10:46
Shawn Wildermuth
Рет қаралды 11 М.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 249 М.
Which dictionary to choose in C# and which one is dangerous
11:12
Nick Chapsas
Рет қаралды 100 М.
How to write "smarter" enums in C#
12:56
Nick Chapsas
Рет қаралды 133 М.
Why Developers Hate "Clean Code"?
14:39
Nick Chapsas
Рет қаралды 47 М.
Where are types allocated in .NET and why people get it so wrong
14:35
The Blazor Competitor is Here!
15:08
Nick Chapsas
Рет қаралды 54 М.
Value & Reference types in C#. Write Better Code!
15:09
Tarodev
Рет қаралды 32 М.
1❤️#thankyou #shorts
00:21
あみか部
Рет қаралды 68 МЛН