Hello World in .NET written using IL code

Поділитися
Вставка
  • Опубліковано 31 тра 2021
  • Subscribe: bit.ly/ChapsasSub
    Become a Patreon and get source code access: / nickchapsas
    Hello everybody I'm Nick and in this video I am going to have a little fun by writting a .NET application that prints Hello World! by emiting IL code. IL or Intermediate Language is the language that C#, VB.NET and F# will all compile into and it's what the CLR or Common Language Runtime, will ultimately execute. C# provides a way to emit that IL code and this can be used in multiple things from building dynamic proxies to speeding up reflection.
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: bit.ly/ChapsasGitHub
    Follow me on Twitter: bit.ly/ChapsasTwitter
    Connect on LinkedIn: bit.ly/ChapsasLinkedIn
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

КОМЕНТАРІ • 46

  • @thinker2273
    @thinker2273 2 роки тому +18

    Metaprogramming never fails to surprise me with each new way of writing code to avoid having to write code.

  • @ivandrofly
    @ivandrofly 3 роки тому +8

    yes, more IL tutorial please!

  • @kano636
    @kano636 3 роки тому +8

    Your HelloWorldWithIL code actually could be translated to IL code using C# as well, creating the HelloWorld inception nightmare

  • @barmetler
    @barmetler 2 роки тому +1

    This is so cool! IL this kind of stuff.

  • @astralpowers
    @astralpowers 3 роки тому +3

    I remember doing this for a university compiler project back in the .NET 2.0 days. But then System.Linq.Expressions in .NET 3.5 made it all obsolete.

  • @matthewblott
    @matthewblott 3 роки тому +1

    Nick's a smart guy.

  • @dragon_programming
    @dragon_programming 2 роки тому

    Does anyone have any idea why Console.Readline can't be called from il?
    I tried it with every kind of method ( methods with return types, methods with parameters,methods without any of these) - all of them work.
    But if you try to use any of the read methods from the console ,the il fails , givinh you a System.Reflection.TargetInvocationException with an InnerException of InvalidProgramException.
    If anyone has a solution i would love to hear it.

    • @jonas9
      @jonas9 Рік тому

      Are you using the value? You can't return a value from a void method.

  • @p4xx07
    @p4xx07 3 роки тому +1

    Why would you want to do this though? What do you get out of it to create assemblies during run time?
    I guess you could have a config file, and then create different assemblies based on the config... But it seems a bit gimmicky

    • @nickchapsas
      @nickchapsas  3 роки тому +2

      Unit testing mocking frameworks are built this way. You can also significantly speed up reflection to be as fast as actual compiled code. Is more use-case specific for sure, but certainly something you should be at least aware of

  • @marna_li
    @marna_li 3 роки тому +1

    The average developer does not need this. But they should at least know about it.
    A typical use case for this is when you build have to generate IL code in memory, like when building a compiler, or for some optimized task.
    And a lot of compile-time tooling is based around Reflection.Emit or Cecil. That can now be replaced by Roslyn and source generators.
    There is even a third-party package called Cecil that is used for inspecting and building assemblies - without dependency on Reflection.Emit.
    Nowadays, people can use Roslyn and source generators to generate high-level C# code at compile-time instead. It is easier to debug, and suits better for most cases.

    • @nickchapsas
      @nickchapsas  3 роки тому +5

      This is partially true. Yes 99% of .NET developers don't need to know how to do this. That being said I disagree with the source generator statement. I think they both have their place for various reasons. Firstly, Source Generators are only supported on specific dotnet version and specific C# versions, while IL emittion works across the board. It is also fundamentally different since one will emit IL code directly while source generation is subject to lowering and then IL emition (which is not the same). You don't get to control IL with SG but you do with IL emit (and some times you need to). Source Generators have a long way until their developer experience becomes acceptable (it is currently horrible to work with). You won't see Moq migrating to source generators anytime soon.
      As a side note, my content is not necessarily there to teach something (that's why I explicitly make it shorter than other people in the same area), but it rather acts as a catalyst to get someone started on a topic. This video is no different.

    • @marna_li
      @marna_li 3 роки тому

      @@nickchapsas I agree. I know that they are not the same, and of course there are limitations.
      What I meant to say is that tools have been using Reflection.Emit for emitting compile-time structure or IDE experiences, in cases where you, today, could use source generators.
      You need know on what level you need to generate code.
      Anyway, I’m a compiler nerd so I have experimented a lot with IL and metadata generation. It is fun generating IL and to see it run 🙂
      Keep up the good work with your channel!

  • @granmasterlincoln
    @granmasterlincoln 3 роки тому

    is london always cold? just asking because i think i never saw you without a coat \o/

  • @CocoszFTW
    @CocoszFTW 3 роки тому +3

    is there any reason to do this? like can you actually out-code the compiler?

    • @nickchapsas
      @nickchapsas  3 роки тому +2

      Technically it depends but I wouldn't try to out-code the compiler because the compiler evolves and might out-code you by upgrading. This is very valuable if for example reflection absolutely is the only way to do something but you want it to be as fast as possible. IL Generation for proxy classes and other things is also a very valid usecase but it might eventually become less relevant as source generators evolve.

    • @MulleDK19
      @MulleDK19 3 роки тому +7

      You can do things that C# doesn't allow. For example, you can make a int ReinterpretFloatAsInt(float x) value by doing
      ldarg.0
      ret
      This will load the first argument onto the evaluation stack, then return the value. Since the argument is float but the method returns int, this will effectively reinterpret it as an int. IE. you'll get the raw integer value of the float, equivalent to return BitConverter.ToInt32(BitConverter.GetBytes(x)); but significantly more performant.
      Just an example.

    • @carpal4489
      @carpal4489 3 роки тому

      @@MulleDK19 just use Bitcast if I'm not wrong.

    • @carpal4489
      @carpal4489 3 роки тому

      Compilers that run on the crl use it to generate IL code

    • @MulleDK19
      @MulleDK19 3 роки тому +1

      ​@@carpal4489 They've added BitConverter.SingleToInt32Bits() in .NET 5. But that's not a language feature. This was just an example of what IL allows.

  • @pabloturnesg
    @pabloturnesg 3 роки тому +1

    Hi nick, what method would you recommend using to store passwords and keys used in source code running in .net core, thanks

    • @sps014
      @sps014 3 роки тому

      Don't store passwords, if possible use hash+randomized salt will provide decent security.

    • @ElSnakeObwb
      @ElSnakeObwb 3 роки тому

      Check out IDataProtector it's in Microsoft.AspNetCore.DataProtection

    • @pabloturnesg
      @pabloturnesg 3 роки тому +1

      @@sps014 I may have not explained myself well, I was talking about api keys and db passwords needed to run the app services, not user passwords.

    • @sps014
      @sps014 3 роки тому

      @@pabloturnesg my bad i assumed something else ...

    • @nickchapsas
      @nickchapsas  3 роки тому +2

      Use a secure key store solution like Azure KeyValut or AWS KMS. I have a video on the subject showing you how to do it.

  • @clearlyunwell
    @clearlyunwell 3 роки тому

    👍🏽

  • @moeenkamali1288
    @moeenkamali1288 3 роки тому +1

    I'm not sure when we really need to write il code directly

    • @nickchapsas
      @nickchapsas  3 роки тому +3

      You don't until you have a usecase for it. Then you do.

    • @sheglova
      @sheglova 3 роки тому

      There aren't many use cases, but one example might be when you need to generate optimized code based on user configuration i.e. you're building a DSL.

    • @temp50
      @temp50 3 роки тому

      @@sheglova I can give you a real world example.
      I had to add an x509 certificate to every assembly built for production.
      I also had to write an x509 cert validator for these assemblies. the method had been added to the LoadAssembly event handler so every managed dll which was loaded by a given assembly was checked if they contained the required certificate.
      And I had to write unit tests for that event handler logic to verify that the cert validation is really doing what it should do.
      So how you do it from a unit test? Exactly, you create an assembly (with a "helloworld"-like method in it), load the assembly from a memory stream with Assembly.Load and trigger the validation logic for positive and negative tests. Of course for positive tests you also have to add a valid certificate to your dynamically created and loaded assembly. :D

  • @amaillo
    @amaillo 3 роки тому +1

    Is that Rider?

  • @acidrazor
    @acidrazor 3 роки тому +3

    Now you just showing off 🤨

  •  2 роки тому

    OMG

  • @sob4655
    @sob4655 2 роки тому

    This is useless. You can't claim to teach IL Emit without any mention of the push/pop sequence of the evaluation stack.

    • @nickchapsas
      @nickchapsas  2 роки тому +1

      Never claimed to teach IL at any point in the video or the title.