2010-06-26 9 views
11

El código siguiente se compila en C# 4.0:más o menos igual sobrecargas

void Foo(params string[] parameters) { } 
void Foo(string firstParameter, params string[] parameters) { } 

¿Cómo sabe el compilador el que la sobrecarga de que está llamando? Y si no puede, ¿por qué el código aún compila?

+7

+1, pregunta interesante, aunque probablemente ya haya sido respondida en las especificaciones. –

Respuesta

13

Es bien especificado en la especificación del lenguaje C#, capítulo 7.4.3.2, "miembro de una mejor función":

De lo contrario, si MP es aplicable en su forma normal y MQ tiene una matriz params y sólo es aplicable en su forma expandida, entonces MP es mejor que MQ

De lo contrario, si MP tiene menos parámetros declarados que MQ, entonces MP es mejor que MQ. Esto puede ocurrir si ambos métodos tienen matrices de params y son aplicables solo en sus formularios expandidos.

Fwiw, el C# Language Specification es un muy documento legible y puede ayudar a resolver estos rompecabezas por sí mismo. Lo tiene en su máquina, encuéntrelo en el directorio de instalación de Visual Studio (como c: \ program files \ microsoft visual studio 9.0) en el subdirectorio vC# \ specifications \ 1033.

Otra buena es el documento estándar Ecma-335, disponible gratuitamente como PDF download. Especifica el comportamiento del CLR y del compilador JIT, excelente material para comprender por qué C# (y el CLR) hacen lo que hacen. Recomendado.

+1

Interesante. Si tomo el código OP y llamo a 'Foo (" uno ")', el compilador selecciona el segundo método (vs2010, .net 4), lo que parece incorrecto según esa cita. La única forma en que logré invocar el primer método fue pasar una matriz de cadenas como único argumento. –

+0

@Fredrik: mi error, me perdí una regla. –

+0

Ahora tiene más sentido :) –

6

En algunos casos, it will decide for you. Por lo tanto, es posible que desee utilizar nombres diferentes en casos como este (o en casos más útiles :-)).

En particular, de los cuatro casos:

 Foo("bar"); 
     Foo("bar", "bar"); 
     Foo(new string[]{"bar", "bar"}); 
     Foo("bar", new string[] { "bar", "bar" }); 

sólo # 1 y # 2 son 'ambigua' (desde # 3 y # 4 coinciden naturalmente sobrecarga 1 y 2 respectivamente).

En los casos de resolución de sobrecarga n. ° 1 y n. ° 2, se elige la sobrecarga n. ° 2 porque tiene un parámetro de serie independiente que coincide con el único/primer parámetro de la invocación.

+0

Eso en realidad tiene sentido. – user230821

+0

Oh sí, tiene sentido. Quise decir que no es muy útil tener esas 2 sobrecargas. – Mau

Cuestiones relacionadas