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

Поделиться
HTML-код
  • Опубликовано: 3 дек 2023
  • 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

Комментарии • 176

  • @local9
    @local9 6 месяцев назад +164

    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 6 месяцев назад +3

      But that's not a click bait title 😉

    • @local9
      @local9 6 месяцев назад +3

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

    • @mikaelsyska
      @mikaelsyska 6 месяцев назад +3

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

  • @vyrp
    @vyrp 6 месяцев назад +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 6 месяцев назад +5

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

    • @highlanderdante
      @highlanderdante 6 месяцев назад +16

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

    • @jongeduard
      @jongeduard 6 месяцев назад +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 6 месяцев назад

      @@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 6 месяцев назад

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

  • @DemoBytom
    @DemoBytom 6 месяцев назад +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 6 месяцев назад

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

    • @Grafsnikers
      @Grafsnikers 6 месяцев назад +1

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

    • @Spartan322
      @Spartan322 6 месяцев назад +1

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

  • @ivank6486
    @ivank6486 6 месяцев назад +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 6 месяцев назад +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 6 месяцев назад

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

    • @warny1978
      @warny1978 6 месяцев назад

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

  • @bslushynskyi
    @bslushynskyi 6 месяцев назад +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.

  • @firestrm7
    @firestrm7 6 месяцев назад +10

    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 6 месяцев назад +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.

  • @louisfrancisco2171
    @louisfrancisco2171 6 месяцев назад +3

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

  • @karthikkrishnaswami3164
    @karthikkrishnaswami3164 6 месяцев назад +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!

  • @mdonatas
    @mdonatas 6 месяцев назад +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)); }

  • @killymxi
    @killymxi 6 месяцев назад +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 6 месяцев назад +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 6 месяцев назад

      I thought it looked like something from Python or the like

    • @louisfrancisco2171
      @louisfrancisco2171 6 месяцев назад

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

  • @S0p0r10
    @S0p0r10 6 месяцев назад +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

  • @MZZenyl
    @MZZenyl 6 месяцев назад +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".

  • @arztje
    @arztje 6 месяцев назад +3

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

  • @talwald1680
    @talwald1680 6 месяцев назад +2

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

  • @AduMaster
    @AduMaster 6 месяцев назад +1

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

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

  • @davidwilliss5555
    @davidwilliss5555 6 месяцев назад +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 .

  • @ryanjeffares8238
    @ryanjeffares8238 6 месяцев назад +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 6 месяцев назад +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 6 месяцев назад +2

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

  • @MayronDev
    @MayronDev 6 месяцев назад +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  6 месяцев назад +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

    • @MayronDev
      @MayronDev 6 месяцев назад

      @@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
      @MayronDev 6 месяцев назад

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

  • @antonzhernosek5552
    @antonzhernosek5552 6 месяцев назад +2

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

  • @isnotnull
    @isnotnull 6 месяцев назад +2

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

  • @joshpatton757
    @joshpatton757 6 месяцев назад +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 6 месяцев назад

      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 6 месяцев назад

      @@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 6 месяцев назад

      ​@@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 5 месяцев назад

      but do not await Beasts(7);

  • @_nikeee
    @_nikeee 6 месяцев назад +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 6 месяцев назад +4

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

    • @LeutnantJoker
      @LeutnantJoker 6 месяцев назад

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

  • @Tsunami14
    @Tsunami14 6 месяцев назад +7

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

  • @JoeFeser
    @JoeFeser 6 месяцев назад

    Thanks!

  • @Yogs01180
    @Yogs01180 6 месяцев назад

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

  • @aspeckt112
    @aspeckt112 6 месяцев назад +5

    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.

    • @DoGGy1110
      @DoGGy1110 6 месяцев назад

      That's true. Unity has == overload for GameObject and it's components

    • @keyser456
      @keyser456 6 месяцев назад +2

      I've never had to use it myself, but I'd guess that's probably the most overloaded operator.

    • @aspeckt112
      @aspeckt112 6 месяцев назад

      @@keyser456Probably a fair assumption, yeah.

    • @diadetediotedio6918
      @diadetediotedio6918 6 месяцев назад +1

      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

    • @Kitulous
      @Kitulous 6 месяцев назад +1

      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)

  • @agailloty
    @agailloty 6 месяцев назад +1

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

  • @bsoter
    @bsoter 6 месяцев назад +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.

  • @SacoSilva
    @SacoSilva 6 месяцев назад

    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

  • @dukefleed9525
    @dukefleed9525 6 месяцев назад

    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.

  • @VeNoM0619
    @VeNoM0619 5 месяцев назад +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.

  • @flybyw
    @flybyw 4 месяца назад

    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.

  • @asedtf
    @asedtf 6 месяцев назад +1

    The Monitor stuff feels like some serious insanity

  • @benoitrousseau4137
    @benoitrousseau4137 6 месяцев назад +1

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

  • @Spartan322
    @Spartan322 6 месяцев назад

    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.

  • @code8986
    @code8986 6 месяцев назад +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 4 месяца назад

      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

  • @gctypo2838
    @gctypo2838 6 месяцев назад

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

  • @biohaz999
    @biohaz999 6 месяцев назад +3

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

  • @acmesoft
    @acmesoft 6 месяцев назад +1

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

  • @guybahar6856
    @guybahar6856 5 месяцев назад

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

  • @pilotboba
    @pilotboba 6 месяцев назад

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

  • @proosee
    @proosee 6 месяцев назад +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

  • @billy65bob
    @billy65bob 6 месяцев назад +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 6 месяцев назад +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)) { ... }

  • @romanhrytskiv6280
    @romanhrytskiv6280 6 месяцев назад

    this video made me smile :)

  • @ekeke7125
    @ekeke7125 6 месяцев назад +1

    Monitor and the lock really surprised me

  • @celiacasanovas4164
    @celiacasanovas4164 6 месяцев назад

    Some of those things have such strong Ruby vibes!

  • @TicoCryptonaut
    @TicoCryptonaut 2 месяца назад

    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.

  • @yunietpiloto4425
    @yunietpiloto4425 6 месяцев назад

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

  • @funkydiddykong
    @funkydiddykong 6 месяцев назад +11

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

    • @asedtf
      @asedtf 6 месяцев назад +2

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

    • @funkydiddykong
      @funkydiddykong 6 месяцев назад

      @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 6 месяцев назад +1

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

    • @user-dg7tu1eb6r
      @user-dg7tu1eb6r 6 месяцев назад

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

  • @Chris-zb5nm
    @Chris-zb5nm 6 месяцев назад

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

  • @lexer_
    @lexer_ 6 месяцев назад

    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.

  • @viophile
    @viophile 6 месяцев назад +1

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

  • @himagainstill
    @himagainstill 6 месяцев назад

    11:37 Filename checks out

  • @ozsvartkaroly
    @ozsvartkaroly 6 месяцев назад

    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
    @ozsvartkaroly 6 месяцев назад

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

  • @aspeckt112
    @aspeckt112 6 месяцев назад +1

    We can all aspire to have a class with a suffix of "Bullshit".

  • @ClickOkYT
    @ClickOkYT 6 месяцев назад

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

  • @orterves
    @orterves 6 месяцев назад +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. 6 месяцев назад +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 6 месяцев назад

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

  • @rsamuseu
    @rsamuseu 6 месяцев назад

    Well, another 6 insane interview questions

  • @lordicemaniac
    @lordicemaniac 6 месяцев назад +2

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

    • @gctypo2838
      @gctypo2838 6 месяцев назад

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

  • @tempusmagia486
    @tempusmagia486 6 месяцев назад

    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.

  • @chriskruining
    @chriskruining 6 месяцев назад

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

  • @WarrenGarabrandt
    @WarrenGarabrandt 6 месяцев назад

    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_ 6 месяцев назад

    Javascript developers are now really considering C# after this vid

  • @MrHeavyRunner
    @MrHeavyRunner 6 месяцев назад

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

  • @lordicemaniac
    @lordicemaniac 6 месяцев назад

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

  • @pillmuncher67
    @pillmuncher67 4 месяца назад

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

  • @diadetediotedio6918
    @diadetediotedio6918 6 месяцев назад

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

  • @devgenesis6436
    @devgenesis6436 6 месяцев назад

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

  • @alexanderkvenvolden4067
    @alexanderkvenvolden4067 6 месяцев назад +1

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

  • @WDGKuurama
    @WDGKuurama 6 месяцев назад

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

  • @Aly_._
    @Aly_._ 6 месяцев назад

    Nice video. Where’d you get your haircut?

  • @OggVorbis69
    @OggVorbis69 6 месяцев назад

    operator overloading is not so foreign for C++ programmers. good old times.

  • @haxi52
    @haxi52 6 месяцев назад

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

  • @anonimxwz
    @anonimxwz 6 месяцев назад

    the async stuff looks like a war crime

  • @FireDragon91245
    @FireDragon91245 6 месяцев назад

    i love the forech range the most its amazing

  • @onetoomany671
    @onetoomany671 6 месяцев назад +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.

  • @AlFasGD
    @AlFasGD 6 месяцев назад +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.

  • @user-no1zm7yn7w
    @user-no1zm7yn7w 6 месяцев назад

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

  • @stas_khavruk
    @stas_khavruk 6 месяцев назад

    Dude just made Ruby from C# by Extension methods xD

  • @1235368
    @1235368 6 месяцев назад

    When you do something for the heck of it.

  • @brkr78
    @brkr78 6 месяцев назад +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.

  • @jakubsvorc322
    @jakubsvorc322 6 месяцев назад

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

  • @shaihulud4515
    @shaihulud4515 6 месяцев назад

    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!

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b 6 месяцев назад

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

  • @PeacefulMindss
    @PeacefulMindss 6 месяцев назад

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

  •  6 месяцев назад

    Monitor 'override' is really weird.

  • @Naton
    @Naton 6 месяцев назад +2

    Time to make F# chaining operator

    • @orterves
      @orterves 6 месяцев назад

      That async operator example looks ripe for creating knockoff computation expressions

  • @themeronz
    @themeronz 6 месяцев назад

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

    • @gctypo2838
      @gctypo2838 6 месяцев назад

      NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

  • @TalicZealot
    @TalicZealot 6 месяцев назад

    This is some cursed stuff dude.

  • @TehGM
    @TehGM 6 месяцев назад

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

  • @PedroHenrique-us5ks
    @PedroHenrique-us5ks 6 месяцев назад

    6 ways to write cursed C#

  • @scuroguardiano9787
    @scuroguardiano9787 6 месяцев назад +1

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

  • @lisascheers9104
    @lisascheers9104 6 месяцев назад

    this video made me scream "NOOOOOOOOOOO"

  • @JSWarcrimes
    @JSWarcrimes 6 месяцев назад

    6 cursed things and other possible C# warcrimes

  • @michaelrall8142
    @michaelrall8142 6 месяцев назад

    yeah, code obfuscation by extension methods 😬

  • @BittermanAndy
    @BittermanAndy 6 месяцев назад +2

    0:46 SUBLIMINAL MESSAGING