Adding a BETTER way to loop in C#

  Рет қаралды 77,923

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 the secret extensibility points of C#, which will allow us to bring an AWESOME feature from Kotlin into the language. Not only we will make it work as if it was an official C# feature but we will also make sure it is really performant and fast.
Workshops
dotnetdays | 20 - 22 Oct | bit.ly/dotnetdays2022workshop
NDC Minnesota | 15 - 18 Nov | bit.ly/ndcminnesota2022workshop
NDC London | 23-27 January 2023 | bit.ly/ndclondon2023
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

Пікірлер: 303
@nickchapsas
@nickchapsas Жыл бұрын
A couple of things I didn't cover in the video. Firsly if you are actually going to use this, make sure you also add an analyzer to warn or error on inappropriate usecases. Also, if you wanna support descending ranges for example foreach(var i in 10..5) you'd need to add a different check in the constructor and MoveNext() to support descending iteration.
@nanvlad
@nanvlad Жыл бұрын
You also need to implement Reset() method to make an iteration variable reusable
@maunguyenvan9296
@maunguyenvan9296 Жыл бұрын
how do you implement for loop with custom step like: for ( int i=0; i
@vincentjacquet2927
@vincentjacquet2927 Жыл бұрын
@@nanvlad You are theorically right. Unfortunately Microsoft gave up on this a while ago, as the Reset method of enumerator generated with yield throw NotSupportedException. Therefore you cannot rely on Reset unless you known which enumerator you are dealing with and how it is implemented.
@kamyker
@kamyker Жыл бұрын
More importantly ref struct won't work in async code. I wonder how slow would be class with pooling. #Edit just change it to plain struct. Even .net List uses non-ref struct Enumerator so shouldn't matter for performance.
@Grimlock1979
@Grimlock1979 Жыл бұрын
@@maunguyenvan9296 You can make an extension method on ValueTuple. So you can say: "foreach (var i in (0..50, 2))". Or you can extend ValueTuple, based on how ranges in Haskell work: they are of the form "[first, second .. last]". So that would be: "foreach (var i in (0, 2..50))"
@reecenoone3113
@reecenoone3113 Жыл бұрын
This is why coding is a form of art… I knew about all these features but never considered putting them together in this way
@looperx
@looperx Жыл бұрын
In your defense the usability of a range with for loops is not something you should have to hack in yourself. It should come with the language.
@EddieVillamor
@EddieVillamor Жыл бұрын
It sure can be such a form of art, especially when you get into clean coding and trying to come up with ways to make the simplest syntax
@kylekeenan3485
@kylekeenan3485 Жыл бұрын
If we all coded in our own forms of "Art" we would be back to the 90's/00's with terrible code rampant everywhere that noone understands and doesn't want to touch.
@EddieVillamor
@EddieVillamor Жыл бұрын
@@kylekeenan3485 or you could end up with a github community with guidelines and standards that everyone follows like we have now. A form of art that people are influenced by and mimic. Art is influenced by each other, not every single person will want uniqueness on every single thing we create. I mean is it not true that while poetry and drawings are limitless, there's really only a select number of ways to create things that make for a better product than other techniques that give the same result. So as with coding, and as it is today, everyone can create code in whatever way they choose, but because it's so artsy, you can write several ways to make the same hello world application, but do we? Nope, we always use the same examples everywhere with the same standards, etc, and we naturally, and typically, want to use the simplest path with the cleanest looking code. So it's just a matter of exposing the art for others to be influenced by.
@kylekeenan3485
@kylekeenan3485 Жыл бұрын
@@EddieVillamor Your talking about a dream. We see people moaning about how agile doesn't help and that is clearly documented and has standards, guidelines, training courses galore. If people under those circumstances can't get it right, then following some unique (art) coding style will be a nightmare. Coding in your own unique style that's unusual and different to standard practices will just cause time delays and tech debt. It could in theory with proper guidance and teaching become useful as you stated but it never does. If people want to deviate from standard practices then it's probably best to keep it in their own personal projects. If you do discover something generally better then write a book 😁.
@DryBones111
@DryBones111 Жыл бұрын
As much as I love the simplicity of the syntax, unless it's implemented in the language itself, I wouldn't use it because it is unexpected. Anyone else coming to the codebase would be confused seeing that and not finding anything about it in the official docs. In a similar vein, I love playing with the implicit operators but they have the downside of hiding what's really happening underneath. You've got to weigh up the benefit with the cost of abstraction as with anything.
@11r3start11
@11r3start11 Жыл бұрын
Its a cool feature that could make DSL even more represented in code. But "unexpected" C# code should be maintained, documented and is not junior-friendly.
Жыл бұрын
Agreed. It is a bit too clever and the benefits are IMHO not that big.
@neociber24
@neociber24 Жыл бұрын
This is a feature that should be baked into C#, I don't really agree with add extension methods for this. I don't get why ranges don't just return an enumerator
@NoGamer256
@NoGamer256 Жыл бұрын
@@fredriksjoborg7021 Let's just get back to C# 5 then it is even more simple.
@phizc
@phizc Жыл бұрын
@@neociber24 re: why ranges doesn't return an enumerator ranges can't always produce a start/end value unless it's provided with a length. It's Start and End properties are Index, not int. E.g. "0..", anything with the hat symbol.. on my phone so I don't know how to type it... the one above the a: â
@DryBones111
@DryBones111 Жыл бұрын
@@NoGamer256 The difference is that official language features are extensively documented and can be found in any codebase. Custom language extensions are a new thing that needs to be learned. If it provides enough value, it can be worth it. Is changing "Enumerable.Range" into ".." worth it? That's up to you.
@KevinInPhoenix
@KevinInPhoenix Жыл бұрын
It never ceases to amaze me how much effort people will spend to save a tiny bit of effort.
@42069_
@42069_ Жыл бұрын
hahahahahhaahaa
@cheebadigga4092
@cheebadigga4092 Жыл бұрын
well this is just an example, you could also provide enumerators for your own types and make them behave this way if appropriate in that situation
@billy65bob
@billy65bob Жыл бұрын
This is what we call a programmer move :^)
@Dimich1993
@Dimich1993 Жыл бұрын
true
@ignaziomessina69
@ignaziomessina69 Жыл бұрын
I definitely want this language feature in future version of C# natively! For me it's really fast to write and clear to read
@Vennotius
@Vennotius Жыл бұрын
Having come from Python to C#, I could see myself really liking this near the beginning of my C# path. But now I have gotten used to how C# works and looks. This is nevertheless interesting from an educational point. And it is a good reminder that one can build your own things to meet your needs or just to make things behave more to your taste.
@R.Daneel
@R.Daneel Жыл бұрын
I expect this to enter the language. It also feels like its exclusion is an oversight (which, of course, it's not). The .. format is just so elegant and self-explanatory.
@Jacobhay09
@Jacobhay09 Жыл бұрын
I love your content. I am 100% self-trought and learned on the job where I work. So I don't get exposed to things as much I as I would like. But your small bite-sized videos keep me thinking about new ways to do things. I am able to take these back to some of our older projects and be a fresh set of eyes on them. Thanks again! I am in MN but due to budget cuts, I lost the funds set aside for training and events this year. Maybe I will be able to check you out next time you are in the citites. Keep up the amazing work!
@LittleRainGames
@LittleRainGames Жыл бұрын
Best way is to start coding at home, and to just try new things and read. Eventually you come across stuff like this.
@dimasveliz6745
@dimasveliz6745 Жыл бұрын
very interesting. Hopefully will be built in. Having this custom classes all around and having to add them as a reference to each project for Syntactic sugar purposes is a tremendously big deal. Thanks for sharing though!
@TheSilent333
@TheSilent333 Жыл бұрын
You continue to blow my mind with these little pearls. Thanks Nick!
@thinker2273
@thinker2273 Жыл бұрын
If/when the Roles & Extensions proposal is implement into C#, you'll be able to not only make anything enumerable, but also implement IEnumerable for any type, so you'd literally be able to use Linq on ranges. You're also able to do the same for GetAwaiter which is what makes the await operator function, and you can even make types besides Task/ and ValueTask/ into acceptable return types for async methods. Extension methods (and hopefully soon Roles & Extensions) is truly one of the best features of C#.
@NoGamer256
@NoGamer256 Жыл бұрын
They started exploring in 2017. I just don't have much hope. There is crowd of people saying that C# is getting too complex and people don't know what to use anymore. I think they listen to them.
@pw.70
@pw.70 Жыл бұрын
I've used enumerators before, but never had it implemented as a feature of the code itself. Genius!
@nekuskus5218
@nekuskus5218 Жыл бұрын
A super interesting way of using extensions! Thanks a lot for this
@Galakyllz
@Galakyllz Жыл бұрын
I didn't even think about creating useful enumerators based on native types. Great video, thanks.
@maskettaman1488
@maskettaman1488 Жыл бұрын
Not a fan of this feature/syntax, but still super cool to see how you'd go about implementing it. Not something I had thought of but can definitely see using in other ways in the future
@anaselhassani2545
@anaselhassani2545 Жыл бұрын
Worked , thanks a lot!
@gui.ferreira
@gui.ferreira Жыл бұрын
That is really a clever idea Nick! Well done. 👏
@alisonhj
@alisonhj Жыл бұрын
I would use it, very elegant, congrats!
@Spherous
@Spherous Жыл бұрын
Omg yesss! This is a feature I very much miss from Rust when using C#. Thanks!
@parkercrofts6210
@parkercrofts6210 Жыл бұрын
Wow thank you so much that really helped
@owns3
@owns3 Жыл бұрын
power of extensions - love it
@Denominus
@Denominus Жыл бұрын
Fun side note. C# actually has quite a few of these "magic methods" that you can implement yourself. The LINQ query syntax is full of them, like being able to use the "from x in y select..." syntax on any type if you add a Select method with the correct signature to that type. I don't normally recommend it because its quite obscure and confusing to most people but its nice to know how the internals of some of these language features work.
@DryBones111
@DryBones111 Жыл бұрын
Your specific example is pretty useful for implementing monadic code with an imperative syntax. I do like it, and it has its merits.
@alirezanet
@alirezanet Жыл бұрын
Great trick! I think we should open an issue in c# repo to support this internally, would be great feature
@TheMAZZTer
@TheMAZZTer Жыл бұрын
Cool, though I wouldn't put a GetEnumerator on int. That seems a recipe for subtle bugs if you intend to iterate through an IEnumerable but accidentally grab a single int first. Normally you'd get a compiler error. So definitely should be careful with implied casts and similar tools like this. Plus if someone else looks at this code... for (var i in 10) ... they're not going to know wtf that is or why it even works. It is difficult to find the extension powering that. At least with the Range they can search the code for uses of the Range type to find it. Pretty cool but I find with foreach loops I don't tend to use normal for loops much. Even when I need the index or to put that index into a separate array, I can use LINQ .Select or .Zip to do that in a foreach (yes probably not efficient, my philosophy is to write nice code and only come back later if there's a performance need). That said I do avoid for because of the verboseness as you said so this does look tempting. Iterating over objects in a collection is usually what I am really wanting in most loops though.
@vuquy711
@vuquy711 Жыл бұрын
Awesome, Nick. I really love your videos!
@kylekeenan3485
@kylekeenan3485 Жыл бұрын
It's a nice idea if it was implemented into C# for all to use, but not as a random thing added to a project. Last thing we need is rewriting the wheel because it looks slightly nicer. This sort of behaviour is what leads to technical debt over a long period of time.
@Kommentierer
@Kommentierer Жыл бұрын
This is actually super cool. Greetings from kotlin, every language has its nice feature we miss elsewhere.
@Mazur_Family_Travel
@Mazur_Family_Travel Жыл бұрын
I even haven’t known about syntax sugar. Nice videos, Nick! Great performance and work you are doing on your channel, thanks!
@carldaniel6510
@carldaniel6510 Жыл бұрын
Neat truck! I will absolutely use this.
@josephizang6187
@josephizang6187 Жыл бұрын
OMG, Nick this is awesome. Thank you.
@KazLA
@KazLA Жыл бұрын
thanks 🙏 Nick!
@pritishranjan
@pritishranjan Жыл бұрын
This is the real beauty of C#. Its not coding mate...it's Art. 👏
@KeithOlson
@KeithOlson Жыл бұрын
I learned a trick in the '80s that I still use today: instead of using 'i'/'j'/etc. for your loops, use 'ii'/'jj'/etc. That way, any time you come across a double letter you *know* that it is a loop variable.
@matthewsheeran
@matthewsheeran Жыл бұрын
Beautiful powerful C# that make it feel - almost - like Python! Great video Nick thankyou!!
@Kingside88
@Kingside88 Жыл бұрын
Yes I like it and would love to see it in C# itself
@renatogolia211
@renatogolia211 Жыл бұрын
Is there any specific advantage on not implementing IEnumerator in the example? I understand the advantages of duck typing for types that we don't own (like the methods extending Range and Index) but whenever possible I'd still prefer using interfaces when available. Also, this is something I'd like MS added to the BCL as it makes very much sense to iterate on a range.
@figloalds
@figloalds Жыл бұрын
6:16 I don't see any problem in going to infinity since it's an Enumerator, the user code can break out of it using some other condition, that's the user-code responsibility, it does make sense. Now if start is from start then maybe count from the end down would make more sense
@nickchapsas
@nickchapsas Жыл бұрын
It actually won't go into infinity the way its implemented. It will just instantly exit the loop
@ronsijm
@ronsijm Жыл бұрын
@@nickchapsas I think what @Felype Rennan means is that it could make sense to make it loop infinity if no end is defined. You'd just have to write something like `foreach (var i in (5..).Where(x => x < 100))` so that a linq extension eventually breaks the looping
@nickchapsas
@nickchapsas Жыл бұрын
@@ronsijm Oh I see. Yeah it might make sense, butthere is no infinity technically since ints have a max value, so you'd need special handling for a feature that doesn't really make sense to me from a language design standpoint. It's why Kotlin itself doesn't allow it too
@AConversationOn
@AConversationOn Жыл бұрын
@@nickchapsas An infinite iterator itself makes sense, so here you /could/ interpret `10..` as `10 forever`: 10,10,10...
@figloalds
@figloalds Жыл бұрын
​@@nickchapsas true. I would implement " is from end" as "Int32.MaxValue" and call it a day, because in practice no indexed loop realistically goes to infinity If the programmer needs something infinite then they'd be using while(true) instead, it's even faster to write and easier to read than foreach(var i in x..) At the same time I think it's useful for if you need (0..).Where(Predicate).Take(200) Where limiting the range to 200 first then applying a filter would produce an incorrect result This is more convenient than requiring the user code to explicitly say (0..Int32.MaxValue).Where.... IMO
@alfredoquintanalopez2265
@alfredoquintanalopez2265 Жыл бұрын
Great!!! I will use it.
@ermancetn
@ermancetn Жыл бұрын
Probably i will not use this technique, but i liked the way how you elegantly implemented it.
@maaadkat
@maaadkat Жыл бұрын
Supporting descending without affecting performance is tough. You don't want an if statement in the middle of MoveNext. Branch Prediction might sort it out, but the generated ASM contains the cmp every time so there's no compiler optimisation breaking the method into two and preselecting which to use. I didn't run a performance test, though, so it might be OK. I tried swapping behaviours in with a Func behind MoveNext() which pointed to named methods (lambdas in structs can't reference instance members), but while the enumerator worked in that it iterated the right number of times, the value in the foreach loop remained 0 which is pretty odd. As if either the value was cached, or copied and different copies used inside and outside the enumerator. What did work was creating an interface with Current and MoveNext, and a static method (yes, interfaces can have static methods!) to get one of two specific implementations (as structs, not ref structs). Structs implementing interfaces can have performance implications with boxing if the structs are cast to and from the interface, but the fact that foreach loops only require Current and MoveNext to exist, and don't depend on IEnumerator, indicates that it's unlikely to be an issue.
@ziaulhasanhamim3931
@ziaulhasanhamim3931 Жыл бұрын
If ref structs are used for enumerators foreach loops can't be used in async methods.
@dcuccia
@dcuccia Жыл бұрын
I've wanted more duck typing for numerics for ages - this is an awesome capability. Replacing Enumerable.Range(...) will go a long way to having functional code look a lot more functional, and quite competitive with Python, Matlab and Ruby for expressiveness. And with the new static abstract interfaces, I'm actually looking forward to building custom Span iterators over large multi-dimensional datasets (across different axes). Thank you Nick!!
@joost00719
@joost00719 Жыл бұрын
I used this feature to be able to await a cancellation token. Awesome stuff, feels like magic :D
@ChristopherSalisburySalz
@ChristopherSalisburySalz Жыл бұрын
I would use it in a personal project for sure. I'm not sure about work. Probably be fine for work because we create extension methods for things from time to time so it's really not any different than that.
@davidnguyen9065
@davidnguyen9065 Жыл бұрын
Most of your us are still learning the crust of .NET, figuring out the ins and outs and the basics. But here u r extending the entire framework and diving deep into its internal source code and showing us how to rewrite parts of .NET to perform better. This is just a no-go zone for most of us
@WillFuqua1987
@WillFuqua1987 Жыл бұрын
A similarly cool "language hack" that's been possible for ages is using the "Add" extension method to implement the JavaScript and Kotlin "spread" behavior for lists, to support syntax like: new List { "a", "b", nestedListOfString };
@ristopaasivirta9770
@ristopaasivirta9770 Жыл бұрын
This looks like something Jon Skeet would have done, I love it :D
@EwertonSilveiraAuckland
@EwertonSilveiraAuckland Жыл бұрын
Amazing.. mind blowing ❤👌🎉
@chefbennyj
@chefbennyj Жыл бұрын
Oh! that is just the best! Yes, let's see some numbers. Very cool
@soverain
@soverain Жыл бұрын
Very interesting! I'm sure there is more to do with this!
@hudsentech8663
@hudsentech8663 Жыл бұрын
Tnx!
@sealsharp
@sealsharp Жыл бұрын
Thats pretty sweet!
@beriu3512
@beriu3512 Жыл бұрын
This is the type of thing that really makes me interested in C#
@user-nh8vd4nv5t
@user-nh8vd4nv5t Жыл бұрын
Reminds me of overflowing c++ code with macros where everything looks cool but you don't understand how it works anymore without reverse engineering them back to normal code
@reecenoone3113
@reecenoone3113 Жыл бұрын
I’m always in two minds about macros. Easy refactoring, terrible readability
@NoGamer256
@NoGamer256 Жыл бұрын
So in Kotlin it is cool cause you can't find out how it works easily. In C# it is bad cause you have to write it yourself. Makes sense.
@user-nh8vd4nv5t
@user-nh8vd4nv5t Жыл бұрын
@@NoGamer256 Its cool for Kotlin because its Kotlin syntax, its bad for C# because its Kotlin syntax.
@WillEhrendreich
@WillEhrendreich Жыл бұрын
Nice, literally anything that's puts c# closer to f# is a win in my book.
@WillEhrendreich
@WillEhrendreich Жыл бұрын
@@MiningForPies oh I agree, wholeheartedly, but the more c# looks and acts f#-ish, the more people will see that f# isn't intimidating, and maybe they will switch to the best dotnet language after that..
@Erlisch1337
@Erlisch1337 Жыл бұрын
@@WillEhrendreich they already switched to C#....
@adassko6091
@adassko6091 Жыл бұрын
Loop like foreach (var i in 0..) actually may make sense in combination with break and yield. That's actually a cool way to write a loop from zero to "infinity" with a counter
@krccmsitp2884
@krccmsitp2884 Жыл бұрын
I'd suggest "infinity" or "from end" would be int.MaxValue then.
@jonathanperis3600
@jonathanperis3600 Жыл бұрын
Please add a PR for this be included on C# 12!
@ZeroSleap
@ZeroSleap Жыл бұрын
I am a stickler for having the rigid syntax of a for loop usually.But i am in love with this extension,seriously thinking of adding it to my projects.But the only concern would be for other people to understand or even run my code if they dont have this extension method.
@SoumeshRanger111
@SoumeshRanger111 Жыл бұрын
You're the most prominent C# instructor on KZbin.
@grainfrizz
@grainfrizz Жыл бұрын
This is so cool
@antonmartyniuk
@antonmartyniuk Жыл бұрын
Looks interesting!
@0xfded
@0xfded Жыл бұрын
Another slight drawback is Range does not support negative numbers, so you can't do -5..5 as you can in Kotlin. It should have been called IndexRange as it's designed to support index ranges rather than value ranges. Still a cool hack if you're ok with non-negative ranges.
@billy65bob
@billy65bob Жыл бұрын
You actually can. e.g. foreach(var i in ^10..0) { } will go from -10 to 0. You'll need this version of the ref struct though. public ref struct RangeEnumerator { private int _current; private readonly int _end; private readonly bool _forward; public RangeEnumerator(Range range) { _current = range.Start.IsFromEnd ? -range.Start.Value : range.Start.Value; _end = range.End.IsFromEnd ? -range.End.Value : range.End.Value; _forward = _end >= _current; if (_forward) _current--; else _current++; } public readonly int Current => _current; public bool MoveNext() => _forward ? ((++_current) = _end); }
@0xfded
@0xfded Жыл бұрын
@@billy65bob Thanks! I didn't think about the ^ operator. And that's some tight code, very impressive.
@HalasterBlackmantle
@HalasterBlackmantle Жыл бұрын
I loved this kind of syntax in Python. So I would use this without a second thought in C#.
@yuGesreveR
@yuGesreveR Жыл бұрын
Actually, this is the first time when I see, that the duck typing in foreach loops can be really useful. I've never thought about ranges in such a context. This is really an elegant approach👍
@BillieJoe512
@BillieJoe512 Жыл бұрын
I never knew this was possible! I always thought a class needs to implement IEnumerable to be used in a foreach loop. as for the feature itself, I think I feel about it similar to Unity's coroutine System: I'm not sure if it is a perversion of existing features or just brilliantly elegant.
@matsnord4092
@matsnord4092 Жыл бұрын
I'm not a c# programmer, have been mostly working with perl, python, js and java. It feels like home for me.
@Galakyllz
@Galakyllz Жыл бұрын
I can imagine making extension methods for tuples of specific types. ex: Tuple contains my repository class (which implements a generic "get all" method) and the total number of records to return ex: Tuple contains my API endpoint (Uri) and JSON data (Object) which returns an array of JSON objects serialized to type T That said, it's probably best to just create custom classes for each of these and implement IEnumerable, but the possibilities are interesting to think about.
@CraigBoland
@CraigBoland Жыл бұрын
I like the terse syntax and would use this. However, most of the looping in my applications is iterating over a collection, so 'foreach(var item in items)' is my typical pattern.
@filipweisser2634
@filipweisser2634 Жыл бұрын
Note that in func programing you can see even x.. (to infinity lazy) and its valid use case where you can stop the loop in the inner implementation.
@DryBones111
@DryBones111 Жыл бұрын
Although if its lazy, you're not really stopping a loop, you're just finished grabbing values from the iterator :)
@PhodexGames
@PhodexGames Жыл бұрын
I didnt knew x..y was an actual operator in C#. Well done.
@LukeVilent
@LukeVilent Жыл бұрын
By necessity, I work on python for the last few years, and I'm kinda used to python loops and find them elegant. But I see languages converge on something that is just easy to write and read, and it's lovely to see C#, my most loved language, to go yet one more step in this direction.
@stratosmav7993
@stratosmav7993 Жыл бұрын
Nice!!!
@davidjsutherland
@davidjsutherland Жыл бұрын
That was fun.
@dennycrane2938
@dennycrane2938 Жыл бұрын
Yeah you can do this type of duck typing to create custom Task classes too, to mimic how Java/Android used to do them. Same way middleware works in asp.
@charles_kuperus
@charles_kuperus Жыл бұрын
Wow. This is damn awesome.
@diadetediotedio6918
@diadetediotedio6918 Жыл бұрын
I really like this syntax. I had seen for some time that it was possible to make conventional arrays support destructuring through extension methods as well (to support a more functional way of dealing with arrays, without having to use Spans [which work very well for that too]), it's interesting see the breadth that you can take this.
@QwDragon
@QwDragon Жыл бұрын
It's very cool, but I think that the normal loop seems better.
@void_star_void
@void_star_void Жыл бұрын
Hey Nick thanks for the video. You also coding in kotlin or just interested in other languages 😁
@jonasex3001
@jonasex3001 Жыл бұрын
It could make sense to use till the end, the user can always exit the loop on whatever condition
@AndrewJonkers
@AndrewJonkers Жыл бұрын
I would love this usage to be available, even as a C# feature. HOWEVER a big caveat for C#: Implementing anything other than what the current Range operator allows will just confuse code intent. That is start..end must be inclusive of start and exclusive of end. So 0..3 has indexes 0,1,2. This is just an implicit unchangeable fact of life for C#.
@Rovsau
@Rovsau Жыл бұрын
I think testing would need to be done with multiple types and scenarios, to see if and when it makes sense to use it. If it is actually overall performant on large collections, it could at least be used to write faster and more readable code at the same time. Though, if a beginner adopts this, I imagine it may be difficult to receive help debugging. If readability is the primary goal, is there a way to make a Loop() method for all types of collections?
@KerchumA222
@KerchumA222 Жыл бұрын
Hey Nick, I would be interested to see if you know of any use cases for the other duck typings in c# (await for example).
@CambleDCS
@CambleDCS Жыл бұрын
Big fan of extension methods in general and this is really nice!
@jeanmartin3256
@jeanmartin3256 Жыл бұрын
Nice, I just like to know in which version it's supported ! Thanks
@TheSimonDavidson
@TheSimonDavidson Жыл бұрын
I do really like the syntax but would you have any concern about a fresh developer coming onto a project that implements this? If the extensions do have custom implementations that may not be obvious, it would be very easy for a new developer to miss that for something that should just be a basic loop.
@nickchapsas
@nickchapsas Жыл бұрын
The same concern I have when senior developers get exposed to new C# features
@TheSimonDavidson
@TheSimonDavidson Жыл бұрын
I think my concern is more that the implementation is in the extension. Depending on who has written it, it could be inclusive or exclusive. I still consider myself a relatively new developer and while this syntax is easily readable, hiding the actual mechanics of it away in an extension class could cause confusion down the line if they then try to use it elsewhere. I guess it's making sure there is decent onboarding to new devs to show them, this ISN'T standard functionality, this is how it works in OUR project.
@CarstenFuehrmann
@CarstenFuehrmann Жыл бұрын
Very interesting, in particular the duck typing part. One downside here is that we still can't call LINQ methods on ranges.
@kvloover
@kvloover Жыл бұрын
doing things like this is one of the funnest things to do in programming, but all my coworkers hate me when I do :D
@2947jasmine
@2947jasmine Жыл бұрын
To avoid the conventional for loop, we are creating an extensions class & getenumerator method. Thus we are making our for loop more consize and readable/presentable. Please let me know what other benefits can we get through this method. I am learning, please correct me if I got this wrong
@PierreGadea
@PierreGadea 9 ай бұрын
I saw a benchmark where Exists was faster than Any. Do you know the reason? I can't find any material on the subject so might make for a good video.
@vorontsovru270895
@vorontsovru270895 Жыл бұрын
About six months ago I set the same goal =) My code came out a little worse, but it will do for an experiment =) To be honest, I somehow didn't think about ref struct then
@lyrion0815
@lyrion0815 Жыл бұрын
Thats an creative way of implementing it. I somewhere saw how you can implement an extension that makes it possible to write "await TimeSpan.FromSeconds(3)" or even "await 3" by making an extension method on int like this public static TaskAwaiter GetAwaiter(this int millis) => return Task.Delay(millis*1000).GetAwaiter();
@xlerb2286
@xlerb2286 Жыл бұрын
I'd perhaps use it in code I owned if I had a lot of for() loops I was dealing with. But I'd be cautious about using it in a team setting. The team would have to agree that it was an extension with a value that exceeded the potential cost of requiring the knowledge that this extension was present, how it worked, and any limitations the implementation may have. For example are the ranges inclusive or exclusive, are descending ranges supported, does it just work with ints or can you use enums, etc. Is usage of this required, recommended, or developer preference? Who maintains that code and how is the team notified if there are any changes made to it that affect behavior? So another words, the same as any other component you consider taking on as a dependency 🙂
@TamanaKun
@TamanaKun Жыл бұрын
I still prefer the classic old for loop. The new one look cool, but i think many peoples will understand the old one better. Plus, dont have to write the extension class is a plus for me
@neociber24
@neociber24 Жыл бұрын
I don't really agree, this one is easier to read and understand, the problem is that is not integrated in the language. Some languages use loops that way: kotlin, rust, swift
@skyppex4076
@skyppex4076 Жыл бұрын
You can do a similar thing with a Deconstructor actually. Just create an extension method for something like a KeyValuePair like this: public static void Deconstruct(this KeyValuePair kvp, out TKey key, out TValue value) { key = kvp.Key; value = kvp.Value; } This will then allow you to write stuff like this: private void Example() { Dictionary dict = new Dictionary(); //Fill it with values foreach ((string key, int value) in dict) { Console.WriteLine($"Key: {key}, Value: {value}"); } } As you can see you end up unwrapping the KeyValuePair automatically into two variables, the key and the value. The same concept works on any table-like structure :D
@Grimlock1979
@Grimlock1979 Жыл бұрын
KeyValuePair already has a Deconstruct method. No need to write your own ;)
@billy65bob
@billy65bob Жыл бұрын
@@Grimlock1979 Some of us are still stuck on .NET 4.7 which doesn't. 😥
@Grimlock1979
@Grimlock1979 Жыл бұрын
@@billy65bob True. They added it recently.
@doge9203
@doge9203 Жыл бұрын
bruh, this is magic
@LeMustache
@LeMustache Жыл бұрын
I wonder why ranges don't implement IEnumerable by default. Are they planning on adding that?
@lordicemaniac
@lordicemaniac Жыл бұрын
but what would be increment?
@LeMustache
@LeMustache Жыл бұрын
@@lordicemaniac I'm not sure what you're asking
@lordicemaniac
@lordicemaniac Жыл бұрын
@@LeMustache range 1..10, should it increment by 1, 2, 5, 10?
@LeMustache
@LeMustache Жыл бұрын
@@lordicemaniac I think it's pretty obvious I'm talking about an implementation that's very close to what Nick shows in this video
@vincentjacquet2927
@vincentjacquet2927 Жыл бұрын
This is a nice trick but this is it, just a trick. Compared to a regular for loop, there are many shortcomings: it does not support negative indexes nor stride other than 1 (or -1 if you support decreasing ranges). Also, in c#, a range 0..10 stops at 9. With the .. syntax, Kotlin ranges are closed whereas c# ranges are open-ended. And BTW, instead of throwing an exception, you could support "From End" indexes if you get the offset with a length of int.MaxValue, instead of getting the value.
@billy65bob
@billy65bob Жыл бұрын
You could also use 'from end' to fix one of the shortcomings; specifically the lack of negatives. :)
@stevepettifer4896
@stevepettifer4896 Жыл бұрын
Elegant? Yes, and a very cool experiment. But would I use it? Probably not. It doesn't really save anything except a few keystrokes and unless your loops routinely deal with larger ranges then there is a performance penalty, albeit a very small one which may or may not add up to something more significant (YMMV of course). And even if you use larger ranges all the time, it's performance neutral and still confers no tangible benefit. Someone else made the point about it being 'unexpected' code and needing maintaining and documenting, and not being junior friendly and I think those are very valid and underrated points. If you are prepared to invest that time and effort and don't mind the extra cognitive load for juniors, albeit a small one but again these things add up, then I guess you could go for it for the sake of elegance but it feels like this is better held up as a practical explanation/example of duck typing than something to use generally.
@jebarcha
@jebarcha Жыл бұрын
Hi. Is there a coupon code for your courses? Thanks.
@CRBarchager
@CRBarchager Жыл бұрын
Very nice feature. I guess it's only a matter of time before it's supported by Microsoft (.NET 8?).
Optimizing String Performance Easily in C#
12:02
Nick Chapsas
Рет қаралды 40 М.
The electrical pattern that will keep your .NET services alive
16:47
Did you find it?! 🤔✨✍️ #funnyart
00:11
Artistomg
Рет қаралды 112 МЛН
where is the ball to play this?😳⚽
00:13
LOL
Рет қаралды 14 МЛН
How To Choose Ramen Date Night 🍜
00:58
Jojo Sim
Рет қаралды 56 МЛН
Why You Might Not Need Interfaces in C# 12
12:43
Nick Chapsas
Рет қаралды 66 М.
I Lied! The Fastest C# Loop Is Even Weirder
11:50
Nick Chapsas
Рет қаралды 45 М.
Unlocking Code Coverage: The Ultimate Guide for .NET Developers
21:16
Don't Use AutoMapper in C#! Do THIS Instead!
16:17
Codewrinkles
Рет қаралды 64 М.
Never write another loop again (maybe)
10:48
Dreams of Code
Рет қаралды 247 М.
SingleOrDefault or FirstOrDefault? When LINQ might harm you
13:35
Nick Chapsas
Рет қаралды 50 М.
Why We ALL Use xUnit over NUnit or MSTest?
17:51
Gui Ferreira
Рет қаралды 6 М.
Value & Reference types in C#. Write Better Code!
15:09
Tarodev
Рет қаралды 32 М.
Git MERGE vs REBASE
16:12
Academind
Рет қаралды 1 МЛН