Después de investigar un poco sobre esto de los decompiladores también encontré una forma de proteger nuestro código un poco ante ataques de ingeniería inversa y decompiladores.

Con eso sólo te quitarás de encima a los programadores novatos, pero realmente te crea una falsa sensación de seguridad,

Busca en google sobre mono Cecil, ildasm, mododis, etc. etc.
El Net Reflector te lo puse porque es el más fácil de usar y te genera el código de C#
Cecil is a library written by Jb Evain (http://evain.net/blog/) to generate and inspect programs and libraries in the ECMA CIL format. It has full support for generics, and support some debugging symbol format.
In simple English, with Cecil, you can load existing managed assemblies, browse all the contained types, modify them on the fly and save back to the disk the modified assembly.
mododis al igual que ildasm, desensambla tu dll o ejecutable, te genera código ensamblador (CIL), puedes modificar el código, agregar o quitar instrucciones, y enseguida con ilasm volver a generar el ejecutable con los cambios realizados. Son herramientas que proporciona el Visual Studio y Mono, ni siquiera tienes que descargar otros programas, más que el propio framework.
Ej. de salida de desensamble (monodis).
monodis Ejecutable.exe >Ejecutable.exe.il
Abriendo el archivo podemos ver instrucciones como:
.namespace WindowsApplication1
{
.class private auto ansi abstract sealed beforefieldinit Program
extends [mscorlib]System.Object
{
// method line 4
.method private static hidebysig
default void Main () cil managed
{
.custom instance void class [mscorlib]System.STAThreadAttribute::'.ctor'() = (01 00 00 00 ) // ....
// Method begins at RVA 0x2075
.entrypoint
// Code size 22 (0x16)
.maxstack 8
IL_0000: call void class [System.Windows.Forms]System.Windows.Forms.Application::EnableVisualStyles()
IL_0005: ldc.i4.0
IL_0006: call void class [System.Windows.Forms]System.Windows.Forms.Application::SetCompatibleTextRenderingDefault(bool)
IL_000b: newobj instance void class WindowsApplication1.Form1::'.ctor'()
IL_0010: call void class [System.Windows.Forms]System.Windows.Forms.Application::Run(class [System.Windows.Forms]System.Windows.Forms.Form)
IL_0015: ret
} // end of method Program::Main
...
Se puede ver como si fuera un lenguaje ensamblador orientado a objetos

Podemos modificar el archivo .il a nuestra conveniencia, por ejemplo:
...
// method line 6
.method private hidebysig
instance default void button1_Click (object sender, class [mscorlib]System.EventArgs e) cil managed
{
// Method begins at RVA 0x209c
// Code size 67 (0x43)
.maxstack 2
.locals init (
string V_0,
string V_1)
IL_0000: ldstr "tres"
IL_0005: stloc.0
IL_0006: ldarg.0
IL_0007: ldfld class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication1.Form1::textBox1
IL_000c: callvirt instance string class [System.Windows.Forms]System.Windows.Forms.Control::get_Text()
IL_0011: stloc.1
IL_0012: ldloc.1
IL_0013: ldloc.0
IL_0014: call bool string::op_Equality(string, string) //Compara la contraseña que has ingresado en el textBox1 con la que tienes almacenada
IL_0019: brfalse.s IL_0037 //Si es falso salta al IL_0037
IL_001d: ldstr "Correcto Mi Cuate" //Si es correcta se sigue por aquí abriendo un Dialogo informandote que es correcta la contraseña
IL_0020: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult class [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string)
IL_0025: pop
IL_0029: ldarg.0
IL_002a: ldfld class [System.Windows.Forms]System.Windows.Forms.Label WindowsApplication1.Form1::label2
IL_002c: ldstr "Que dijeron ya puse la frase"
IL_0031: callvirt instance void class [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)
IL_0036: ret
IL_0037: ldstr "Incorrecto" //Aquí es donde salta si no pusieron bien la contraseña
IL_003c: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult class [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string)
//Como que se me ocurre agregarle al programa que si
//te equivocas cambie el label1 por 'Otra propuesta', así de fácil es modificar el código
pop
ldarg.0
ldfld class [System.Windows.Forms]System.Windows.Forms.Label WindowsApplication1.Form1::label1
ldstr "Otra propuestra"
callvirt instance void class [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)
ret
ret
} // end of method Form1::button1_Click
...
Ya después con el ilasm volver a generar el ejecutable
ilasm Ejecutable.exe.il Ejecutable.exe
Y tendremos la versión modificada.
Tal vez también te interese el ManagedSpy (
http://msdn.microsoft.com/en-us/magazine/cc163617.aspx)
Realmente no le veo mucha utilidad, ya que si alguien es capaz de proteger su código, alguien también será capaz de desprotegerlo (Si hay forma de hacerlo, también hay forma de deshacerlo). Es realmente, una perdida de tiempo y de recursos, además de correr el riesgo de que tu código no trabaje como esperas.
SaludOS