6 INSANE Things You Didn't Know You Could Write in C#

2023 ж. 3 Жел.
50 087 Рет қаралды

Use code REFAC20 and get 20% off the brand new "Refactoring for C# Developers" course on Dometrain: dometrain.com/course/from-zer...
Use code CLEAN20 and get 20% off the brand new "Deep Dive into Clean Architecture" course on Dometrain: dometrain.com/course/deep-div...
Get the source code: mailchi.mp/dometrain/lr1gtif05em
Become a Patreon and get special perks: / nickchapsas
Hello everybody, I'm Nick, and in this video, I will show you 6 insane things you can write in C# that you probably didn't know you could do, and maybe that's for good reason.
Workshops: bit.ly/nickworkshops
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: github.com/Elfocrash
Follow me on Twitter: / nickchapsas
Connect on LinkedIn: / nick-chapsas
Keep coding merch: keepcoding.shop
#csharp #dotnet

Пікірлер
  • Alternative Title, "6 quick ways to get your repo access revoked" Some examples, I can see some use cases, but most (specially the date) would likely get me shouted at. Heard you like some async, so I put some more async inside your async.

    @local9@local95 ай бұрын
    • But that's not a click bait title 😉

      @mikaelsyska@mikaelsyska5 ай бұрын
    • @@mikaelsyskaIts Nick, I'd still click it.

      @local9@local95 ай бұрын
    • @@local9 yes, no matter what the title is, I would still watch.

      @mikaelsyska@mikaelsyska5 ай бұрын
  • For those who are wondering: in `async async async(async async) => await async`, we have: * First async: the keyword. * Second async: the method return type. * Third async: the method name. * Forth async: the parameter type. * Fifth async: the parameter name. * Sixth async: the parameter again.

    @vyrp@vyrp5 ай бұрын
    • That's obvious, but why c# allows method name and parameter's to be async? That's the question

      @DoGGy1110@DoGGy11105 ай бұрын
    • Async is a contextual keyword, for backwards compatibility reasons. Same goes for var, await, get and set and many others

      @highlanderdante@highlanderdante5 ай бұрын
    • The main point for me is that the async keyword was introduced in C# version 5, and in order not to break compatibility with older code, the compiler team probably decided that they couldn't just make such variable or parameter names suddenly forbidden. So they really had to work around it and support it both as a identifiers as well as keywords, depending on the place where they are used. However, on the other hand, I am not sure at this point why I cannot make a variable called await, but while I can call it async.

      @jongeduard@jongeduard5 ай бұрын
    • @@jongeduard You can make a variable named "await", just not inside an async method. Because 'await' has a special meaning in that context. On the other hand, 'async' only has a special meaning as a modifier in the method declaration.

      @louisfrancisco2171@louisfrancisco21715 ай бұрын
    • @@louisfrancisco2171 Thanks! That explains it all, and also confirms the compatibility thing even more! However, what must have confused me, when I quickly test on Sharplab, I get a compiler error for it in top level code too (no problem since the whole top level code thing far newer). When I make a synchronous local function inside that, the variable name is accepted. LOL. Thinking further that actually makes sense too, since top level code is optionally asynchronous too, as soon as the first await call is written.

      @jongeduard@jongeduard5 ай бұрын
  • The new insane thing to do in c#8 is using static methods in interfaces. It's powerfull as hell. There's loads of interfaces already existing. For example, if you want a type to be parsable from string, just derive it from IParsable. You know that particular type will have Parse and TryParse methods. If you create a generic class/method like this : public void TestParse(string value) where T : IParsable you'll then be able to write : T v = T.Parse(value); This comes with many more interfaces such as IAdditionOperators, ISubstractionOperators, ITrigonomertyFunctions... This means you can define you own class with compiled standardized names. That's so cool ! This also means that you no longer have to create functions for each numeric type; you can handle everything at once : public T Addition(T num1, T num2) where T : IAdditionOperators => num1 + num2; for example, here's the signature for my matrix class : public sealed partial class Matrix : IFormattable, IEquatable, IEquatable, IEquatable, IEquatable, ICloneable, IAdditionOperators, ISubtractionOperators, IEqualityOperators, IEqualityOperators, IMultiplyOperators, IMultiplyOperators, IMultiplyOperators, IDivisionOperators, IUnaryNegationOperators, IUnaryPlusOperators where T : struct, IFloatingPoint, IPowerFunctions, ITrigonometricFunctions, IRootFunctions It now handles both double and float

    @warny1978@warny19785 ай бұрын
    • But that's C# 11 and dotnet 7, not C# 8.

      @jongeduard@jongeduard5 ай бұрын
    • @@jongeduard You are right, but i did not get it work properly in c#11

      @warny1978@warny19785 ай бұрын
  • 2:07 I would have gone one bit further and add an implicit conversion to string. 8:50 "Be very careful with your extension methods on types you don't own" There is usually less need to add extension methods on types you do own. I tried some crazy stuff, just for the fun of it. For example: WriteLine(from x in 42 where 7 select x); This writes "[0, 7, 14, 21, 28, 35, 42]"

    @louisfrancisco2171@louisfrancisco21715 ай бұрын
  • The first one is a technique Nuke Build uses for their paths. It also has implicit operator to cast it to string.

    @DemoBytom@DemoBytom5 ай бұрын
    • When I saw it in Nuke I thought it is so cool usage of operator overload

      @stassss2011@stassss20115 ай бұрын
    • If I’m not mistaken, this technique was added to standard library in Python

      @Grafsnikers@Grafsnikers5 ай бұрын
    • @@Grafsnikers Its better part of the C++ standard since 2017 when std::filesystem::path came in C++17

      @Spartan322@Spartan3225 ай бұрын
  • Just remember that you can get the length of the string directly from memory (unsafe obviously): TypedReference ref = __makeref(str); IntPtr ip = **(IntPtr**) &ref; var ptr = (int*) ip.ToPointer(); var len = *(ptr+2);

    @ivank6486@ivank64865 ай бұрын
  • Well, in my experience the bullshit I did with C# I can name 2 things: extension methods for Span/ReadOnlySpan and overloading operator+ that accepts 2 different types and returns an enumerable of 3rd type. Something like Papa+Mama=Kids.

    @bslushynskyi@bslushynskyi5 ай бұрын
  • One interesting that got junior devs stumped in my project was the use of implicit and explicit and how the hell incompatible types get assigned and yet compiled!

    @karthikkrishnaswami3164@karthikkrishnaswami31645 ай бұрын
  • For the lock-monitor insanity my guess is that the lock is a syntax sugar which translates to the usage of System.Threading.Monitor and since you just created your own version of it it takes precedence over the BCL when compiling.

    @firestrm7@firestrm75 ай бұрын
    • My first thought was for debugging concurrency issues. One thing I've done fairly recently was create an IDisposable class that takes a lock on an object and releases it upon disposal, but also allowing parameterizing a timeout before the lock fails, as well as logging a message if the lock is held for too long - and I could just replace the lock(obj) with a using(...). This class ended up helping a lot with some very improperly-threaded legacy code. If I altered the Monitor class like this I might have been able to get the diagnostics I needed much earlier.

      @gctypo2838@gctypo28385 ай бұрын
  • Something which fits nicely to this theme is Add() method duck-typing and collection initialization. So you could have something like new List { "2023-12-05" }; given that you have an extension method: public static void Add(this List col, string param) { col.Add(DateTime.Parse(param)); }

    @mdonatas@mdonatas5 ай бұрын
  • We did use the Extensions on int to create dates for our unit test. IT IS really nice to read in tests that require different dates and such

    @S0p0r10@S0p0r105 ай бұрын
  • This is one of my favorite videos as of late. "How the hell can we do this?" Always a winner. :)

    @arztje@arztje5 ай бұрын
  • Hehe, glad I shared Jared's async madness on Reddit the other day. It also highlights why the language design team are so careful when working with contextual keywords, for example in relation to the proposed "semi-auto properties" (exposing the implicit backing field of properties the "field" contextual keyword), in situations where you might already have a field named "field".

    @MZZenyl@MZZenyl5 ай бұрын
  • That fileinfo operator is exactly how python's recommended pathlib.Path object works.

    @talwald1680@talwald16805 ай бұрын
  • the Monitor lock thing I could see maybe for debugging where you could log out which thread got the lock. But Heisenberg would rear his ugly head and the logging would change the timing of whatever thing you were trying to debug .

    @davidwilliss5555@davidwilliss55555 ай бұрын
  • 6:13 - `foreach (var i in 5..10)` - actually seems sensible and would be nice to have in the language, I think. Immediately, I went to check if `foreach (int i in [5,6,7,8,9,10])` would work, but unfortunately, it complains that there is no target type...

    @killymxi@killymxi5 ай бұрын
    • I think a lot of languages have this feature. Rust has it so you can do `for i in 0..5 { }`. It is so convenient.

      @davidbottiau5408@davidbottiau54085 ай бұрын
    • I thought it looked like something from Python or the like

      @CRBarchager@CRBarchager5 ай бұрын
    • You are just missing a 'new' before those square brackets.

      @louisfrancisco2171@louisfrancisco21715 ай бұрын
  • I saw most of these on a reddit post recently. Guessing you got the idea from the same post? The third one (range extensions) I've implemented myself and have been using for a few years, it's a shame it's not part of the default Range class/syntax.

    @MayronDev@MayronDev5 ай бұрын
    • I had shown 3/6 of them already in other videos in the past, one was from twitter which i mentioned and one was from a talk from Jared Parsons

      @nickchapsas@nickchapsas5 ай бұрын
    • @@nickchapsas Ah, maybe these must have been going round the internet for a while then. Either way, love your explanations on them and thanks for sharing!

      @MayronDev@MayronDev5 ай бұрын
    • Just odd timing as I thought I had deja-vu lol

      @MayronDev@MayronDev5 ай бұрын
  • Monitor.Enter is the funniest thing I've ever seen so far 🤣

    @isnotnull@isnotnull5 ай бұрын
  • The first one is a thing in the C++ standard library. The filesystem::path class has / overloaded to append any string or path-like object. It feels wrong in a way, but actually quite ergonomic, and nice to know that path separators are all taken care of properly

    @ryanjeffares8238@ryanjeffares82385 ай бұрын
    • that's better than using bit shift operators for printing to streams and reading from streams but it's in the same ballpark

      @Kitulous@Kitulous5 ай бұрын
    • @@Kitulous Yeah, the shift operators were... A Decision. I pretty much exclusively use superior third party libraries for those things lol

      @ryanjeffares8238@ryanjeffares82385 ай бұрын
  • For the async one, I wonder if that's from then they first introduced the keyword... so it wouldn't break existing code?

    @Tsunami14@Tsunami145 ай бұрын
  • I've used the integer awaiting before in a serious project, one that required lots of intricate precise timing. But instead of making custom awaiters on integers directly, I created a new class that was covariant with integer, and awaited that. (with the minor abstraction of 'beat', as this was timing against music, and so the length of time represented by a beat scaled with a 'tempo' setting) This and a simple static method to return beat let me 'await Beats(2)'.

    @joshpatton757@joshpatton7575 ай бұрын
    • But in that case, if you care about performance, I would have chosen to wrap it inside a struct and definitely not a class. There is no reason to allocate memory on the heap for 1 single integer value. Wrapping and int in a class instead of a struct is basically another way of boxing, al be it not in the popular terms.

      @jongeduard@jongeduard5 ай бұрын
    • @@jongeduard Absolutely true in general practice. What I am describing has both a small instance size, wraps a single value, and is immutable - all indicators towards a struct as the preferred approach. This particular case, however, had one reason why I went class over struct: those beats get passed around a lot. And I mean a lot. Since structs are value types, both referencing and any casting that happens as they get passed around and used generates more boxing and unboxing than using a struct saves. As a class though, just needed to pass the references around and saved that overhead. It also helps that I owned the only hardware that ever ran on, so knew exactly what the limitations were and didn't have to fine tune performance beyond what was needed to run the show - this was a live procedural music generator/lighting controller, that was generating both individual notes of the music and controlling individual movements/hue changes for the gobos.

      @joshpatton757@joshpatton7575 ай бұрын
    • ​@@joshpatton757 A struct containing an Int32 is 4 just bytes, the size of the int. While A reference is actually a pointer and is 8 bytes on a 64bit system. A class containing an Int32 needs both 8 bytes for each reference, as well as 4 bytes for the actual int value. When you have a struct that is no larger than 16 bytes, you are always the most efficient with a struct, both in CPU performance as well as in memory, even if you are copying it a million times. And that is exactly what Spans are as well, they are ref structs that contain both a pointer and a length value. And my personal benchmarks show even 24 byte structs to still be pretty memory efficient, I yet have to find out why exactly. Larger structs are indeed less memory efficient than reference types, but they often still win in CPU performance over reference types most of the time. This is purely because of GC overhead, always slowing down things. For each newly created reference to an object, the GC is doing extra work to track it. If you really need to pass references because you actually need to share the same thing between methods, the fastest thing is to use ref parameters to your struct. Then you don't have the copy problem at all, giving you both CPU and memory efficiency back.

      @jongeduard@jongeduard5 ай бұрын
    • but do not await Beasts(7);

      @ralfwarnat9257@ralfwarnat92574 ай бұрын
  • That last one was also missing "public class var" to demonstrate the full sillyness of context-based keywords

    @antonzhernosek5552@antonzhernosek55525 ай бұрын
  • async can probably be used as a type or identifier because it was added later to C#, when there was already code that used that as a name. So in some contexts, the keyword can be used as an identifier. Same story with nameof.

    @_nikeee@_nikeee5 ай бұрын
  • I used the Monitor technique to replace System.Net.Quic with OpenSSL and QUIC Datagram support on Windows 10 back in .Net 6 when .Net 7 was in preview and only supported Windows 11 with TLS 1.3 in SChannel. Used with conditional preprocessor to target different versions of runtimes.

    @flybyw@flybyw3 ай бұрын
  • actually we learn everyday with you Nick, Thank you 😁😁

    @Yogs01180@Yogs011805 ай бұрын
  • Thanks!

    @JoeFeser@JoeFeser5 ай бұрын
  • Bizarre operators usage in C#* *Me*: Nuts! *Also me trying to do anything in F#*: Yeah, ok, first things first - let's wrap this two-arguments function with some bizarre operator.

    @bsoter@bsoter5 ай бұрын
  • The overloading of `operator /` done in `FilePath` seems quite normal if you're familiar with C++ and `std::filesystem::path`.

    @AduMaster@AduMaster5 ай бұрын
  • The first one has the same behavior as the Path class in the Python pathlib library.

    @agailloty@agailloty5 ай бұрын
  • Operator overloads are a fascinating feature that I think most people should avoid. I ran into some code a while back where someone had done an overload of the "==" operator, which resulted in utterly bizarre null handing behaviour. It scared me enough that I now write all my null checks as "x is null" or "x is not null", which is actually semantically way more pleasing anyway.

    @aspeckt112@aspeckt1125 ай бұрын
    • That's true. Unity has == overload for GameObject and it's components

      @DoGGy1110@DoGGy11105 ай бұрын
    • I've never had to use it myself, but I'd guess that's probably the most overloaded operator.

      @keyser456@keyser4565 ай бұрын
    • @@keyser456Probably a fair assumption, yeah.

      @aspeckt112@aspeckt1125 ай бұрын
    • You would use them when creating specific value types, or if you are in your own codebase and/or framework and want to do something curious, but otherwise I would not recommend it usually

      @diadetediotedio6918@diadetediotedio69185 ай бұрын
    • unity moment although in that case the overloaded `==` operator actually has a purpose as it also checks if the object is destroyed (it's not usable anymore but the object reference is not null yet)

      @Kitulous@Kitulous5 ай бұрын
  • Can you please do a video (if you haven't already) on all the uses and contexts of the "ref" keyword? I know one of them, but not the rest. Thank you!

    @code8986@code89865 ай бұрын
    • ref means passing the reference of a value type, for example when you have an int as parameter, normally we pass a copy of the int to it, even the mothed edits the int value, it wound affect the original variable we passed, and if you allow the method to change it, pass (ref i) to it, in this case the method body has the reference to that int variable, any change on the int variable will affect the value itself

      @richardzheng5774@richardzheng57744 ай бұрын
  • The monitor thing could be useful to make a distributed lock. Immediately came to mind because I had to solve this exact problem just days ago

    @SacoSilva@SacoSilva5 ай бұрын
  • can you make a video of ActionResult, IActionResult, IResult and Result and the differences. Why and When we need to use each case?

    @acmesoft@acmesoft5 ай бұрын
  • What about some IDisposable ones? Especially for the monitor thing. Await using lock = new Lock();

    @biohaz999@biohaz9995 ай бұрын
  • Looks like you were browsing Reddit a few days ago and used a post for inspiration

    @Voiden0@Voiden05 ай бұрын
    • I had shown 3/6 of them already in other videos in the past; one was from Twitter, which I mentioned, and one was from a talk from Jared Parsons. The Reddit post just reminded me this would be a good video idea, but it was full of things I've shown myself

      @nickchapsas@nickchapsas5 ай бұрын
    • @@nickchapsas What was your favorite example from the video?

      @Voiden0@Voiden05 ай бұрын
  • The most insane thing I've done in C#? One time, I reversed an array without using Stack Overflow

    @christian.levesque@christian.levesque5 ай бұрын
    • Only insane if that took you less time than another developer looking it up and spending the time on something else ;)

      @LeutnantJoker@LeutnantJoker5 ай бұрын
  • 6:00 This trick is cooler with ranges, i.e. 0..5 It's also the only one I'd consider useful... strictly with ranges only... Well, maybe with a ValueTuple variant for setting the step size...

    @billy65bob@billy65bob5 ай бұрын
    • no, add an extension method Step for it! public static RangeWithStep Step(this Range rng, int step) => new(rng, step); foreach (var i in 0..5.Step(2)) { ... }

      @Kitulous@Kitulous5 ай бұрын
  • I like range extension to facilitate in foreach (not for integers, though), in fact, I don't quite understand why language don't have it by default - I mean, shouldn't ranges be iterable? Path joining - I think this a (rare) valid use case for operator overloading - I see no harm here. Rest is... well... no comment, lol

    @proosee@proosee5 ай бұрын
  • Wasn't the raw object locking as a mutex the old canonical way of locking stuff in C#? If I remember correctly it was because having a separate object as the mutex instead of locking the container itself is cleaner and less error prone supposedly. I could see that make sense in wrapper containers that maintain multiple internal representations for example but I never really understood the argument more generally tbh.

    @lexer_@lexer_5 ай бұрын
  • You say "Dont do this" but I have to say these are nice. As long as the extensions aren't GLOBAL, and only used with specific "using namespace", I see it as no different than other extension methods.

    @VeNoM0619@VeNoM06194 ай бұрын
  • For the lock-monitor, you can do something like "smart" using

    @guybahar6856@guybahar68564 ай бұрын
  • The date and path joining tricks might come from someone trying to replicate the C++ standard library, those features were standardized relatively recently.

    @benoitrousseau4137@benoitrousseau41375 ай бұрын
  • I like the idea of piping file paths and I'd never thought about it. Is the only counterpoint that other developers will be confused by it? I'm tempted to keep using it.

    @TicoCryptonaut@TicoCryptonautАй бұрын
  • duck typing in c# is extremely powerful, imagine what you can do if the switch operator/expression were able to resolve which "case" go into, by calling a special method (or a method on an interface, why not) on the type that need to be switched on....i hope they will do it one day.

    @dukefleed9525@dukefleed95255 ай бұрын
  • this video made me smile :)

    @romanhrytskiv6280@romanhrytskiv62805 ай бұрын
  • I want to know more about the "Monitor" technique. I want to extend the Nunit or Xunit Assert classes but I can't so I'm surprised with that...

    @ClickOkYT@ClickOkYT5 ай бұрын
  • 9:06 is a nice technique for a malware to do some source code infection

    @yunietpiloto4425@yunietpiloto44255 ай бұрын
  • 1. This technique is extremely useful in any language because it allows you to join values together in a clearly regulated way that's still easy to read. Use it where it clearly would make sense to, if you start overriding != to produce a class you really should be beat upside the head 6. Dear God, its type of crap that makes the most vexing parse sound trivial.

    @Spartan322@Spartan3225 ай бұрын
  • @03:04: a Microsoft manager probably won't showcase Jetbrains products, and only Jetbrains ReSharper / Rider can do certain refactorings. So I have doubts about that course's completeness (in terms of how to do them automatically).

    @ozsvartkaroly@ozsvartkaroly5 ай бұрын
  • The Monitor stuff feels like some serious insanity

    @asedtf@asedtf5 ай бұрын
  • When you were beginning to show the lock statement, I was thinking "will we try to goto into a locked lock statement maybe?". It didn't turn out that way, but I'm curious if it's possible. 🤔 (So can goto be used to enter a lock)

    @ozsvartkaroly@ozsvartkaroly5 ай бұрын
  • As a general rule, probably don't do most of these. But, conceptually, how they work can be interesting and useful.

    @gctypo2838@gctypo28385 ай бұрын
  • 11:37 Filename checks out

    @himagainstill@himagainstill5 ай бұрын
  • Some of those things have such strong Ruby vibes!

    @celiacasanovas4164@celiacasanovas41645 ай бұрын
  • As I watch this, David Letterman's "Stupid Pet Tricks" comes to mind.

    @pilotboba@pilotboba5 ай бұрын
  • Why would you not use am embedded language for file paths? It's common practice in Python, it's there in the standard library (pathlib.Path).

    @pillmuncher67@pillmuncher673 ай бұрын
  • Basically you can create all sort of these interesting things with the power of Extensions. That's why I loved C#.

    @Chris-zb5nm@Chris-zb5nm5 ай бұрын
  • Monitor and the lock really surprised me

    @ekeke7125@ekeke71255 ай бұрын
  • Well, another 6 insane interview questions

    @rsamuseu@rsamuseu5 ай бұрын
  • I personally do not appreciate any kind of trickery. The simpler it is, the better.

    @viophile@viophile5 ай бұрын
  • Sir would love to see .net AI content..langchain vector search etc.. any plans?

    @devgenesis6436@devgenesis64365 ай бұрын
  • We can all aspire to have a class with a suffix of "Bullshit".

    @aspeckt112@aspeckt1125 ай бұрын
  • Insane C# techniques that no one in their right mind will use - except course the C# team, who will probably add them to the base language in the next release.

    @orterves@orterves5 ай бұрын
    • Actually / operator is used in some projects and is a very nice feature, for example in Nuke build automation library to provide path concatenation

      @volan4ik.@volan4ik.5 ай бұрын
    • @@volan4ik. I know - just joking that many recent C# versions have come with new language features that modify the look of the language quite drastically (mostly for the better, it is to be said). It's good though - it can be hard to justify adopting approaches that are unconventional, if beneficial, when they are just some random NuGet library; when they are implemented within the language itself there's not so much second guessing using them when they are useful.

      @orterves@orterves5 ай бұрын
  • whenever I see creative uses of opperator overloading I hear the jojo "ooooh noohh" meme in my head :P

    @crazychris0905@crazychris09055 ай бұрын
  • Maybe you could show some things that are flat out impossible in C#.

    @funkydiddykong@funkydiddykong5 ай бұрын
    • C# is Turning Complete, so it's an empty list technically

      @asedtf@asedtf5 ай бұрын
    • @asedtf I know of one niche thing, hooking functions used by the GC such as GlobalMemoryStatusEx. Managed code does not like being run in that context and will throw. So there are things.

      @funkydiddykong@funkydiddykong5 ай бұрын
    • You can really do anything with it, even GPU programming (there are some transpillers from IL to cuda code for example)

      @diadetediotedio6918@diadetediotedio69185 ай бұрын
    • For example, if you use unsafe code, you can allocate and delete an instance of any class just like in C++

      @user-dg7tu1eb6r@user-dg7tu1eb6r5 ай бұрын
  • loved first one with overload for /, also pipe was awesome, have to try it some time

    @lordicemaniac@lordicemaniac5 ай бұрын
  • maybe not insane, but using monads will do quite interesting transformation to your code and flow

    @lordicemaniac@lordicemaniac5 ай бұрын
    • Reminder that awaitable tasks are already monads in C# with language-level support.

      @gctypo2838@gctypo28385 ай бұрын
  • 11:06 Buffalo buffalo, Buffalo buffalo buffalo, buffalo Buffalo buffalo.

    @alexanderkvenvolden4067@alexanderkvenvolden40675 ай бұрын
  • 7:13 Well, this is not unrecommendable I think, some modern languages like Rust and Kotlin have similar ways of looping

    @diadetediotedio6918@diadetediotedio69185 ай бұрын
  • Nice video. Where’d you get your haircut?

    @Aly_._@Aly_._5 ай бұрын
  • Javascript developers are now really considering C# after this vid

    @J_i_m_@J_i_m_5 ай бұрын
  • Your scientists were so preoccupied with whether or not they could, they didn't stop to think if they should.

    @WarrenGarabrandt@WarrenGarabrandt5 ай бұрын
  • Mine is just evil, not proud. Create a Console class with WriteLine method that prints "Compilation error" in a project of a newbie that didn't know about namespaces.

    @tempusmagia486@tempusmagia4865 ай бұрын
  • The Monitor is really something. How does that even work, not complaining about existing class/conflict... Hmm

    @MrHeavyRunner@MrHeavyRunner5 ай бұрын
  • This looks like something one could use to troll/haze the new hire. async async async is my favorite, the foreach-thing is almost usefull.

    @brkr78@brkr785 ай бұрын
  • i love the forech range the most its amazing

    @FireDragon91245@FireDragon912455 ай бұрын
  • Can't wait to have some python nerd make a package called pysharp or Cspy or whatever, with all the magic stuffs x)

    @WDGKuurama@WDGKuurama5 ай бұрын
  • my favorite is Infinite await sequence: Var ret = await await...... await 3;

    @user-no1zm7yn7w@user-no1zm7yn7w5 ай бұрын
  • Enumerating a range of integers that way (a..b) actually sounds pretty neat. But I would need built-in support from the language out of the box, doing it custom like this is the smelliest of smells.

    @onetoomany671@onetoomany6715 ай бұрын
  • operator overloading is not so foreign for C++ programmers. good old times.

    @OggVorbis69@OggVorbis695 ай бұрын
  • They should have just made the range type enumerable. Not really sure why they didn't.

    @haxi52@haxi525 ай бұрын
  • Ha, didn't know `lock` had such semantics

    @user-tk2jy8xr8b@user-tk2jy8xr8b5 ай бұрын
  • Dude just made Ruby from C# by Extension methods xD

    @stas_khavruk@stas_khavruk5 ай бұрын
  • Some smells Python lol so I hate it, but the lock() one is kinda cool.

    @PeacefulMindss@PeacefulMindss5 ай бұрын
  • When you do something for the heck of it.

    @1235368@12353685 ай бұрын
  • Dude, what are you waiting for? Actually an async of an async of async of async of asynce...Yeah, totally describes the state I'm in, most of my life!

    @shaihulud4515@shaihulud45155 ай бұрын
  • This video is basically WAT by Gary Bernhardt, but redone in C# 😂

    @themeronz@themeronz5 ай бұрын
    • NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

      @gctypo2838@gctypo28385 ай бұрын
  • the async stuff looks like a war crime

    @anonimxwz@anonimxwz5 ай бұрын
  • The last thign with async async async... it scares me, because it turns C# into javascript LOL

    @jakubsvorc322@jakubsvorc3225 ай бұрын
  • I cannot wait until async becomes a normal keyword and the async bs is no longer valid. Same goes for var, and many other contextual keywords that should no longer be accepted as valid identifiers.

    @AlFasGD@AlFasGD5 ай бұрын
  • Alright, time to update my codebase with some cool stuff 😈

    @scuroguardiano9787@scuroguardiano97875 ай бұрын
  • Could I maybe use that monitor class override to use default timeout to lock keyword? So that all my locks would timeout, instead of wait indefinitely in case of deadlock? I am now using IDisposable LockWithTimeout(this object lck) ... method and "using" keyword to do the locking, but this would be much, much pretier.

    @PetrVejchoda@PetrVejchoda5 ай бұрын
  • This is some cursed stuff dude.

    @TalicZealot@TalicZealot5 ай бұрын
  • 6 ways to write cursed C#

    @PedroHenrique-us5ks@PedroHenrique-us5ks5 ай бұрын
  • Time to make F# chaining operator

    @Naton@Naton5 ай бұрын
    • That async operator example looks ripe for creating knockoff computation expressions

      @orterves@orterves5 ай бұрын
  • People are afraid of a lot of nightmare fuel. This is so cursed so it beats any horror to date.

    @TehGM@TehGM5 ай бұрын
  • this video made me scream "NOOOOOOOOOOO"

    @lisascheers9104@lisascheers91045 ай бұрын
  • Monitor 'override' is really weird.

    5 ай бұрын
  • 0:46 SUBLIMINAL MESSAGING

    @BittermanAndy@BittermanAndy5 ай бұрын
  • 6 cursed things and other possible C# warcrimes

    @JSWarcrimes@JSWarcrimes5 ай бұрын
KZhead