2011-11-05 9 views
9

Leí un par de artículos que dicen que con la introducción de argumentos con nombre en C# 3.0, el nombre de los parámetros ahora es parte del contrato público. ¿Es esto cierto y qué significa exactamente? Ejecuté una prueba simple y cambiar el nombre de un parámetro en MyLib.dll no rompió MyApp.exe que llamó al método usando un argumento con nombre con el nombre original, creo que porque el compilador de C# sobrecargó la resolución en tiempo de compilación, y generó IL no sabe nada sobre el nombre del parámetro. Esto es lo que el código desensamblado mira reflector:¿Es un cambio de nombre de parámetro en C# un cambio de ruptura de tiempo de ejecución?

private static void Main() 
{ 
    bool CS$0$0000 = true; 
    Class1.DoSomething(CS$0$0000); 
    Console.ReadKey(); 
} 

... y este es el código fuente original:

static void Main() { 

    MyLib.Class1.DoSomething(a: true); 

    Console.ReadKey(); 
} 
+0

Sí, lo entendiste bien, no está rompiendo. Venir con un escenario en el que se está rompiendo es difícil, no puedo pensar en un escenario de enlace tardío donde sí lo haga. –

Respuesta

19

Leí un par de artículos que dicen que con la introducción de argumentos con nombre en C# 3.0, el nombre de los parámetros ahora es parte del contrato público. ¿Es esto cierto, y qué significa exactamente?

Es cierto que los nombres de los argumentos son parte del contrato público, pero la declaración contiene dos errores.

El error más obvio es que los argumentos con nombre se introdujeron en C# 4.0, no en C# 3.0.

Pero el error más sutil es mucho más importante. La introducción de argumentos con nombre en C# 4.0 no hizo ahora hace que los nombres de los parámetros sean parte del contrato público de un método. Los nombres de los parámetros eran siempre parte del contrato público porque los idiomas distintos de C# tenían la función de argumentos nombrados. En particular, VB siempre ha admitido argumentos con nombre.

Por lo tanto, cambiar el nombre de un parámetro en una biblioteca fue siempre un cambio de última hora para la compilación de VB. Ahora también es un cambio decisivo para la recompilación de C#, pero eso no significa que antes era seguro y ahora es peligroso. Siempre fue peligroso.

C# no es el único lenguaje .NET, no con diferencia. Cuando cambia parte de la superficie visible públicamente de un tipo, corre el riesgo de romper programas en cada idioma. C# tener o no tener una característica no cambia ese hecho.

11

El problema es, supongamos que tiene una API pública de este modo:

public void Foo(bool a = false) 
{ 
    //.... 

La persona que llama puede escribir una aplicación que lo utiliza, así:

Foo(a: true); 

Si cambia el método de:

public void Foo(bool aBetterName = false) 
{ 
    //.... 

Ahora, de repente, el código de la persona que llama no pudiera compilar, como el compilador (tan pronto como se ponen al día con su nueva biblioteca) ya no ver un parámetro llamado a.

+0

Spot on y claro como el cristal. Rock en –

+1

Sí, entiendo que es un cambio en tiempo de compilación. –

+0

@MaxToro: Eso es todo lo que significa. El contrato público es fijo, porque romperá (en tiempo de compilación) a otros llamantes. Sin embargo, no es un cambio en el tiempo de ejecución (como agregar un parámetro), ya que la sustitución se maneja en tiempo de compilación. Tenga en cuenta que cambiar el valor predeterminado, sin embargo, no hará que la otra persona que llama se actualice, ya que todo se maneja en tiempo de compilación. (Los argumentos Opcionales/Nombrados son puramente un truco de tiempo de compilación) –

Cuestiones relacionadas