You cannot prevent decompiling, if you compile into MSIL (intermediate language). In such case you need to use obfuscation
For a deeper discussion on the subject check out this post .NET obfuscation tools/strategy
You can find a similar discussion here How can I obfuscate my c# code, so it can't be deobfuscated so easily?
You can also opt to generate a native image using Ngen.exe for a specific platform - that will bypass the IL and generate compiled processor specific machine code, and that one is pretty much safe from standpoint of reverse - engineering.
Using an IL is a quite common design choice - and it has it's drawbacks and benefits - the main ones being easier support of multiple languages on one platform, and multiple target platforms, i.e cross platform
To get a glimpse of some of the benefits of using IL - check this out - stackoverflow.com/questions/1926386/…
Java also uses an intermediate language - java bytecode - javaworld.com/article/2077233/core-java/bytecode-basics.html