2011-09-13 9 views
9

Duplicar posible:
How does the method overload resolution system decide which method to call when a null value is passed?nulo resolución de sobrecarga literal tipo de parámetro

Ésta es una pregunta acerca de por qué el compilador elige una cierta sobrecarga cuando se pasa un valor nulo literal como parámetro, demostrada por string.Format sobrecargas.

cadena.Formato arroja un ArgumentNullException cuando se utiliza el literal nulo para el parámetro args.

string.Format("foo {0}", null); 

El método de formato tiene algunas sobrecargas.

string.Format(string, object); 
string.Format(string, object[]); 
string.Format(IFormatProvider, string, object[]); 

Correr a través del código decompiled, la excepción de los args literales nulos se lanza desde el segundo método. Sin embargo, los siguientes ejemplos llaman al primer método anterior (como se esperaba) y luego llama al segundo, que llama al tercero y luego devuelve simplemente "foo".

string x = null; 
string.Format("foo {0}", x); 

string y; 
string.Format("foo {0}", y = null); 

Pero string.Format("foo {0}", null) llama el segundo método anterior y resulta en una excepción nula. ¿Por qué el compilador decide que el literal nulo coincide con la segunda firma de método en lugar de la primera en este caso?

+3

Quizás amplíe el título/alcance si esto abarca varargs en un sentido más general (si no es cadena.Formato específico) ... –

+0

Pete, probablemente sea consciente de esto (y no es una respuesta a su pregunta) pero aunque lo mencionaría; para evitar esta excepción, puede usar 'String.Formato ("Prueba {0}", String.Empty); '. Todo lo mejor. – MoonKnight

+2

Pregunta duplicada: http://stackoverflow.com/q/5173339/25727. En resumen: la resolución de sobrecarga prefiere tipos más específicos. Por lo tanto, elige la matriz porque 'object' es el tipo más inespecífico en .NET. – Jan

Respuesta

3

yo supongo que simplemente object[] es más específica que object y ser null asignable a object[] que el primero se recogió. (7.5.3.2 Mejor miembro de función en las especificaciones de C#).

mismo ocurre si se intenta:

void Foo(object o) {} 
void Foo(object[] arr) {} 

Foo(null); //Foo(object[]) gets called. 
0

No se puede dar el 100% de certeza, pero mi mejor conjetura sería el siguiente ...

Si estaba escribiendo personalmente a un compilador y que tenía que hacer frente con elegir qué función sobrecargada utilizar según los parámetros pasados, naturalmente iteraría en la lista y encontraría la mejor coincidencia. Me imagino que hay algo a lo largo de estas líneas implementado en el compilador de C#.

Por lo tanto, esto me sugiere que "sobrecarga 2" (en su ejemplo) es anterior a la "sobrecarga 1" y así se encuentra una coincidencia y la iteración se rompe, O el compilador está configurado para usar la última sobrecarga de coincidencia.

Por supuesto, en su ejemplo 2 que pasa x e y. Es fácil hacer coincidir la "sobrecarga 1" cuando se hace coincidir una cadena con el objeto, mientras que una cadena no puede coincidir con el objeto [] y, por lo tanto, "sobrecarga 2" no es una coincidencia válida.

Cuando pasa directamente nulo, esto coincide con "sobrecarga 1" y "sobrecarga 2", por lo que vuelve al punto de ser el primero encontrado en la lista o el último encontrado.

EDITAR: Por lo tanto, resulta que el compilador esencial decide en función de qué parámetros son más específicos. Y object [] si es más específico ese objeto.

Cuestiones relacionadas