Developer's Diary

12 noviembre, 2014

Constantes, haciendo prestidigitación en .NET

Filed under: .net, ASP.Net, Awesome, MVC4, Web — Etiquetas: , , , , — jnavero @ 11:42 PM

Pues si, este no es un post de inyección DLL ni de MVC (Aunque es aplicable). Me apetecía escribir sobre algo que nos pasó en el trabajo hace tiempo.

Aunque creas que tienes este tema dominado, las cosas no siempre son como se pintan y esto es uno de esos casos…

La receta:
– Para este post he preparado una aplicación de consola en .NET
– Una Dll que es donde vamos a hacer las pruebas.

Para hacer las labores de este post, he creado un proyecto de consola y otro proyecto de librerías (DLL).
Como siempre, se añade la referencia del proyecto (DLL) en el proyecto de consola

El proyecto pinta de la siguiente forma:
proyectoConstantes

En la DLL está el siguiente Código:

namespace ConsTest
{
public class TestConst
{
public const string CONSTANTE = "PRUEBA DE UNA CONSTANTE";
}
}

Por otro lado en la aplicación de consola tengo el siguiente código:

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var constString = ConsTest.TestConst.CONSTANTE;
Console.Write(constString);
Console.ReadLine();
}
}
}

Si ejecutamos este código, obtenemos esto:
EjecucionConstantepng

Ahora viene todo el tema y el propósito real de este post y el divertimento de todo esto 🙂
para no equivorcarnos y hacerlo bien, lo mejor, es crear una carpeta en alguna parte (yo usaré c:temp) y copio los dos archivos ejecutables del proyecto, es decir, tal como queda en la siguiente captura:
carpetas

Si ahora ejecutamos el proyecto en la carpeta que hemos copiado debe ejecutarse correctamente. Lo normal y lo esperado.

Ahora vamos a modificar la DLL del proyecto de esta forma:

namespace ConsTest
{
public class TestConst
{
public const string CONSTANTE = "OTRA PRUEBA DE EJEMPLO";
}
}

Compilamos la nueva DLL con la constante cambiada y vamos a sobreescribir la DLL que copiamos anteriormente en c:temp (en mi caso)
y lanzo la pregunta. ¿Que pensáis que sucederá?

(… Se hizo el silencio …)

Bueno, lo normal es que al cambiar la DLL se cambia el texto que se muestra con el Console.Write y punto y final.

Peeeeeeeeeeeero, si esto fuese así no hubiese hecho este post 🙂 y aquí está el truco. Se sigue mostrando el texto que pusimos al principio.

Ahora la pregunta es si hemos cambiado la DLL el texto de la DLL ha cambiado y efectivamente el texto en la DLL se ha cambiado.
¿Pero por que no se cambia el texto que se muestra?

Pues la respuesta es simple y es que las constantes en .NET son como referencias. Cuando existe una de estas referencias en el código el compilador la traduce y lo cambia por el valor de la constante, de esta forma en nuestro ejecutable el valor de la constante está escrita a fuego y no usa la DLL que hemos creado para nada.

En el próximo post terminare el tema de la inyección.

Anuncios

1 comentario »

  1. Muy interesante!

    Parece una inconsistencia pero Eric Lippert* se defiende 🙂


    If you change the value of a const then it was not a constant.

    The idea that you would change the value of a constant means that you are doing something logically impossible, and so of course things will break; you’re doing something that you said you would not do. If you go around lying to the compiler, and it hurts when you do that, then stop lying to the compiler.

    * Eric es el ex lider del compilador de C#

    http://stackoverflow.com/a/9116587/4264

    Comentario por Santi — 15 noviembre, 2014 @ 10:41 AM


RSS feed for comments on this post. TrackBack URI

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: