0

There are cases when we build "something" at runtime. Well known examples of that are EntityFtamework, Automapper. A lot of articles describe how to do something like this with Expressions, Reflection emit, DynamicMethod (which is reflection emit essentially).

But there is an easier way to do. We can dynamically create some source code, compile it to assembly, load this assembly and here we go. It's easier because you as C# programmer create C# code. In order to use expressions and reflection emit you have to learn how to do that and I think this it not the easiest topics.

Why compiling of source code at runtime is less popular approach than Expression and Reflection emit?

  • Because compiling arbitrary source code at runtime, loading it and then executing it also requires a non insignificant amount of reflection, so why go to the extra step of doing that if you could just use reflection from the get go. Plus, writing code that itself writes code isn't trivial and has little to do with "C# programmers creating C# code" – MindSwipe Aug 08 '22 at 11:36
  • It's slow, it's nearly impossible to secure because it allows arbitrary code, it's brittle because a syntax error is really easy to introduce (and likely breaks the entire flow) and it relies on an actual C# compiler, which in turn needs to be versioned. It's only "easier", at first, the maintenance costs are significant. For more intricate code generation scenarios you would still prefer to move it to compile time, through the use of things like T4 templates and the new [source generators](https://learn.microsoft.com/dotnet/csharp/roslyn-sdk/source-generators-overview). – Jeroen Mostert Aug 08 '22 at 11:37
  • As for `Expression<>`, it generally has poor performance because .NET doesn't cache them, and generating hashes (for equivalence) is non-trivial: https://stackoverflow.com/questions/19678074/caching-compiled-expression-tree – Dai Aug 08 '22 at 11:49
  • @MindSwipe , if I want create some class which should be created based on some already compiled code or on some settings or user input, the only way is to create this type dynamically. I can't use reflection, because I need to have something I could to invoke. Or I can? Why I'm asking about that, that's because it seems to me that C# code generation is easier than IL code generation or expression generation. – Volodymyr V. Aug 08 '22 at 16:58
  • @JeroenMostert all these things "it allows arbitrary code, it's brittle because a syntax error is really easy to introduce" will not be present in any kind of code generation? Maybe in case with Expressions you can't write arbitrary code which helps you to avoid syntax errors, but from one side it restricts you to do what you really want, from other side it doesn't save you from making logical errors which I think are harder to diagnose compared with syntax errors. It's what about expressions. What about IL? I think it allows you also to create arbitrary code with all that stuff. Am I wrong? – Volodymyr V. Aug 08 '22 at 17:10
  • @JeroenMostert about some specific compiler features which are depend on version, this is the interesting thought. T4 I thinks you can use only for generation of code which based on your raw source code. You can't use it to generate code which will be based on some already compiled library. Or you can? About source generators, it's relatively new feature. Do you think it will replace IL emit approach in future? If you are interested in code generation should you learn IL emit or today it's better to start of learning of source generators? – Volodymyr V. Aug 08 '22 at 17:19
  • 1
    Source generators cannot replace IL emitting because there will always remain scenarios where code can only be produced at runtime and not at compile time. However, where possible you should focus on compile-time code generation because it's easier and faster. – Jeroen Mostert Aug 09 '22 at 08:14

0 Answers0