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

Поділитися
Вставка
  • Опубліковано 6 жов 2024
  • Use code REFAC20 and get 20% off the brand new "Refactoring for C# Developers" course on Dometrain: dometrain.com/...
    Use code CLEAN20 and get 20% off the brand new "Deep Dive into Clean Architecture" course on Dometrain: dometrain.com/...
    Get the source code: mailchi.mp/dom...
    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/nickwor...
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: github.com/Elf...
    Follow me on Twitter: / nickchapsas
    Connect on LinkedIn: / nick-chapsas
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

КОМЕНТАРІ • 167

  • @local9
    @local9 10 місяців тому +166

    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.

    • @mikaelsyska
      @mikaelsyska 10 місяців тому +3

      But that's not a click bait title 😉

    • @local9
      @local9 10 місяців тому +3

      @@mikaelsyskaIts Nick, I'd still click it.

    • @mikaelsyska
      @mikaelsyska 10 місяців тому +3

      @@local9 yes, no matter what the title is, I would still watch.

  • @vyrp
    @vyrp 10 місяців тому +98

    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.

    • @DoGGy1110
      @DoGGy1110 10 місяців тому +5

      That's obvious, but why c# allows method name and parameter's to be async? That's the question

    • @highlanderdante
      @highlanderdante 10 місяців тому +16

      Async is a contextual keyword, for backwards compatibility reasons. Same goes for var, await, get and set and many others

    • @jongeduard
      @jongeduard 10 місяців тому +5

      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.

    • @louisfrancisco2171
      @louisfrancisco2171 9 місяців тому

      @@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.

    • @jongeduard
      @jongeduard 9 місяців тому

      @@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.

  • @louisfrancisco2171
    @louisfrancisco2171 9 місяців тому +4

    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]"

  • @ivank6486
    @ivank6486 10 місяців тому +5

    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);

  • @warny1978
    @warny1978 10 місяців тому +16

    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

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

      But that's C# 11 and dotnet 7, not C# 8.

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

      @@jongeduard You are right, but i did not get it work properly in c#11

  • @DemoBytom
    @DemoBytom 10 місяців тому +27

    The first one is a technique Nuke Build uses for their paths. It also has implicit operator to cast it to string.

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

      When I saw it in Nuke I thought it is so cool usage of operator overload

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

      If I’m not mistaken, this technique was added to standard library in Python

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

      @@Grafsnikers Its better part of the C++ standard since 2017 when std::filesystem::path came in C++17

  • @killymxi
    @killymxi 10 місяців тому +6

    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...

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

      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.

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

      I thought it looked like something from Python or the like

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

      You are just missing a 'new' before those square brackets.

  • @firestrm7
    @firestrm7 10 місяців тому +11

    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.

    • @gctypo2838
      @gctypo2838 10 місяців тому +5

      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.

  • @mdonatas
    @mdonatas 10 місяців тому +3

    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)); }

  • @bslushynskyi
    @bslushynskyi 10 місяців тому +4

    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.

  • @karthikkrishnaswami3164
    @karthikkrishnaswami3164 10 місяців тому +4

    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!

  • @ryanjeffares8238
    @ryanjeffares8238 10 місяців тому +8

    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

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

      that's better than using bit shift operators for printing to streams and reading from streams but it's in the same ballpark

    • @ryanjeffares8238
      @ryanjeffares8238 10 місяців тому +2

      @@Kitulous Yeah, the shift operators were... A Decision. I pretty much exclusively use superior third party libraries for those things lol

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

    The overloading of `operator /` done in `FilePath` seems quite normal if you're familiar with C++ and `std::filesystem::path`.

  • @talwald1680
    @talwald1680 10 місяців тому +2

    That fileinfo operator is exactly how python's recommended pathlib.Path object works.

  • @MayronWoW
    @MayronWoW 10 місяців тому +6

    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.

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

      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

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

      @@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!

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

      Just odd timing as I thought I had deja-vu lol

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

    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 .

  • @Tsunami14
    @Tsunami14 10 місяців тому +7

    For the async one, I wonder if that's from then they first introduced the keyword... so it wouldn't break existing code?

  • @arztje
    @arztje 10 місяців тому +3

    This is one of my favorite videos as of late. "How the hell can we do this?" Always a winner. :)

  • @antonzhernosek5552
    @antonzhernosek5552 10 місяців тому +2

    That last one was also missing "public class var" to demonstrate the full sillyness of context-based keywords

  • @MZZenyl
    @MZZenyl 10 місяців тому +3

    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".

  • @code8986
    @code8986 10 місяців тому +2

    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!

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

      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

  • @_nikeee
    @_nikeee 10 місяців тому +2

    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.

  • @christian.levesque
    @christian.levesque 10 місяців тому +4

    The most insane thing I've done in C#? One time, I reversed an array without using Stack Overflow

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

      Only insane if that took you less time than another developer looking it up and spending the time on something else ;)

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

    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

  • @joshpatton757
    @joshpatton757 10 місяців тому +8

    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)'.

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

      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.

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

      @@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.

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

      ​@@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.

    • @ralfwarnat9257
      @ralfwarnat9257 9 місяців тому

      but do not await Beasts(7);

  • @proosee
    @proosee 10 місяців тому +3

    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

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

    The first one has the same behavior as the Path class in the Python pathlib library.

  • @billy65bob
    @billy65bob 10 місяців тому +2

    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...

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

      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)) { ... }

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

    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.

  • @isnotnull
    @isnotnull 10 місяців тому +2

    Monitor.Enter is the funniest thing I've ever seen so far 🤣

  • @biohaz999
    @biohaz999 10 місяців тому +3

    What about some IDisposable ones? Especially for the monitor thing. Await using lock = new Lock();

  • @leandroteles7857
    @leandroteles7857 3 місяці тому

    With the new "Extension Everything" feature coming in C# 13 we will be able to add the "/" operator directly to string, enabling this path concatenation hack without a helper class.

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

    The date and path joining tricks might come from someone trying to replicate the C++ standard library, those features were standardized relatively recently.

  • @MonkeyVaughan
    @MonkeyVaughan 10 місяців тому +2

    I remember working on PL/1 on the mainframe (I love that language with fond memories) but that 'async' example reminded me of something that broke my heart that you could do with PL/1... IF IFIF = IF THEN IFIFIF = IFIFIF; something to do with being able to use keywords when you probably shouldn't, it's just mischievous eh!

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

    can you make a video of ActionResult, IActionResult, IResult and Result and the differences. Why and When we need to use each case?

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

    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.

  • @guybahar6856
    @guybahar6856 9 місяців тому

    For the lock-monitor, you can do something like "smart" using

  • @funkydiddykong
    @funkydiddykong 10 місяців тому +11

    Maybe you could show some things that are flat out impossible in C#.

    • @AvenDonn
      @AvenDonn 10 місяців тому +2

      C# is Turning Complete, so it's an empty list technically

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

      @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.

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

      You can really do anything with it, even GPU programming (there are some transpillers from IL to cuda code for example)

    • @егор-ш2о5з
      @егор-ш2о5з 10 місяців тому

      For example, if you use unsafe code, you can allocate and delete an instance of any class just like in C++

  • @flybyw
    @flybyw 7 місяців тому

    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.

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

    9:06 is a nice technique for a malware to do some source code infection

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

    The Monitor stuff feels like some serious insanity

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

    As I watch this, David Letterman's "Stupid Pet Tricks" comes to mind.

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

    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.

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

      Actually / operator is used in some projects and is a very nice feature, for example in Nuke build automation library to provide path concatenation

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

      @@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.

  • @TicoCryptonaut
    @TicoCryptonaut 6 місяців тому

    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.

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

    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

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

    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.

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

    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.

  • @Chris-zb5nm
    @Chris-zb5nm 10 місяців тому

    Basically you can create all sort of these interesting things with the power of Extensions.
    That's why I loved C#.

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

    As a general rule, probably don't do most of these. But, conceptually, how they work can be interesting and useful.

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

    I personally do not appreciate any kind of trickery. The simpler it is, the better.

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

    actually we learn everyday with you Nick, Thank you 😁😁

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

    Monitor and the lock really surprised me

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

    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.

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

    whenever I see creative uses of opperator overloading I hear the jojo "ooooh noohh" meme in my head :P

  • @lordicemaniac
    @lordicemaniac 10 місяців тому +2

    maybe not insane, but using monads will do quite interesting transformation to your code and flow

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

      Reminder that awaitable tasks are already monads in C# with language-level support.

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

    11:37 Filename checks out

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

    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)

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

    Some of those things have such strong Ruby vibes!

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

    The Monitor is really something. How does that even work, not complaining about existing class/conflict... Hmm

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

    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.

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

    @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).

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

    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).

  • @brkr78
    @brkr78 10 місяців тому +2

    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.

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

    Thanks!

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

    Well, another 6 insane interview questions

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

    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.

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

    Your scientists were so preoccupied with whether or not they could, they didn't stop to think if they should.

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

    Javascript developers are now really considering C# after this vid

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

    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.

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

    Sir would love to see .net AI content..langchain vector search etc.. any plans?

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

    Can't wait to have some python nerd make a package called pysharp or Cspy or whatever, with all the magic stuffs x)

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

    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.

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

    They should have just made the range type enumerable. Not really sure why they didn't.

  • @leandroteles7857
    @leandroteles7857 2 місяці тому

    For the "extension nonsense" example, I got an even better approach:
    var today= 30 / November / 2023;
    Just define a helper struct with static readonly members for each month, overriding "/" operator accordingly. And also put a "global using static" for that struct, so the month names can be unqualified 🤣🤣🤣

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

    7:13
    Well, this is not unrecommendable I think, some modern languages like Rust and Kotlin have similar ways of looping

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

    The last thign with async async async... it scares me, because it turns C# into javascript LOL

  • @HoussamR-x7e
    @HoussamR-x7e 10 місяців тому

    my favorite is Infinite await sequence:
    Var ret = await await...... await 3;

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

    Dude just made Ruby from C# by Extension methods xD

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

    loved first one with overload for /, also pipe was awesome, have to try it some time

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

    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!

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

    this video made me smile :)

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

    This video is basically WAT by Gary Bernhardt, but redone in C# 😂

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

      NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

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

    the async stuff looks like a war crime

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b 10 місяців тому

    Ha, didn't know `lock` had such semantics

  • @Aly_._
    @Aly_._ 10 місяців тому

    Nice video. Where’d you get your haircut?

  • @1235368
    @1235368 9 місяців тому

    When you do something for the heck of it.

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

    i love the forech range the most its amazing

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

    Some smells Python lol so I hate it, but the lock() one is kinda cool.

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

    Monitor 'override' is really weird.

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

    C# can achieve "Unions", the same way the c++ phenomenon works. It lets you overlap primitive types onto each other.
    [StructLayout(LayoutKind.Explicit)]
    public struct MyStruct
    {
    [FieldOffset(0)] public uint MyUint;
    [FieldOffset(0)] public int MyInt;
    [FieldOffset(0)] public float MyFloat;
    [FieldOffset(0)] public byte Byte0;
    [FieldOffset(1)] public byte Byte1;
    [FieldOffset(2)] public byte Byte2;
    [FieldOffset(3)] public byte Byte3;
    }
    These will occupy the same memory and only one type needs to be initialized.
    Marshal.SizeOf will give you the combined size though, which makes no sense to me.

  • @Naton
    @Naton 10 місяців тому +2

    Time to make F# chaining operator

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

      That async operator example looks ripe for creating knockoff computation expressions

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

    11:06 Buffalo buffalo, Buffalo buffalo buffalo, buffalo Buffalo buffalo.

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

    People are afraid of a lot of nightmare fuel. This is so cursed so it beats any horror to date.

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

    Alright, time to update my codebase with some cool stuff 😈

  • @PedroHenrique-us5ks
    @PedroHenrique-us5ks 10 місяців тому

    6 ways to write cursed C#

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

    6 cursed things and other possible C# warcrimes

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

    yeah, code obfuscation by extension methods 😬

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

    Overloading of operators is pure crap. Never do that.

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

    This is some cursed stuff dude.

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

    Never used #define in C? 😅