2012-05-25 9 views
5

tengo el siguiente par de métodos de extensión, que están en el mismo espacio de nombres y montaje:La resolución del método en métodos de extensión con los parámetros opcionales

public static class DateTimeExtensions 
{ 
    public static string NullSafeToString(this DateTime? possiblyNullDateTime, string format, string nullString = "") 
} 

public static class NullableExtensions 
{ 
    public static string NullSafeToString<T>(this Nullable<T> nullable, string nullString = "") where T : struct 
} 

Mi pregunta es acerca de la resolución de métodos. La siguiente llamada (de otro espacio de nombres) resuelve a ObjectExtensions.NullSafeToString cuando esperaba DateTimeExtensions.NullSafeToString:

DateTime? dateTime; 
// ... 
dateTime.NullSafeToString("yyyyMMdd"); 

Extracción del parámetro opcional de DateTimeExtensions.NullSafeToString hace que se resuelve como se esperaba.

La sección 7.6.5.2 de la especificación de C# describe el orden de los espacios de nombres buscados, pero como lo anterior está en el mismo espacio de nombres, espero que use las reglas en la sección 7.6.5.1.

pensé que coincide DateTimeExtensions.NullSafeToString porque:

  • Aunque las dos tendrán un primer tipo de parámetro de Nullable<DateTime>, pensé un método no genérica (es decir, sin el parámetro de tipo) sería considerado primero .
  • I, aunque las listas de parámetros sería considerado sin sus parámetros opcionales primeros

¿Alguien puede aclarar por qué se está recogiendo ObjectExtensions.NullSafeToString sobre DateTimeExtensions.NullSafeToString?

(Aparte: de otras discusiones aquí, sospecho que algunas personas pueden desaprobar el uso de la semántica del método de extensión para hacer la desreferenciación nula, pero me parece que para escenarios limitados como este, hacen que el código sea más legible. Sé que Nullable.ToString ya es nulo seguro porque el objeto Nullable en sí mismo no es nulo, pero que no da cabida a los parámetros del contenido ToString, y me parece que el método explícitamente nombrado indica el intento nulo seguro.)

+2

resolución de sobrecarga se aplica "menos argumentos == mejor". –

Respuesta

1

Su problema no tiene nada que ver con el método de extensión. Se trata de la resolución de sobrecarga y los parámetros opcionales. (7.5.3 resolución de sobrecarga de C# spec) Puede probar este código

public static string NullSafeToString(DateTime? possiblyNullDateTime, string format, string nullString = "") 
    { 
     return string.Empty; 
    } 
    public static string NullSafeToString<T>(Nullable<T> nullable, string nullString = "") where T : struct 
    { 
     return string.Empty; 
    } 
    static void Test() 
    { 
     DateTime? datetime = DateTime.Now; 
     NullSafeToString(datetime, "yyyyMMdd"); 
    } 
+0

Gracias por su respuesta. Todavía no tengo claro por qué está eligiendo ObjectExtensions.NullSafeToString sobre DateTimeExtensions.NullSafeToString. De 7.5.3.1: "Si MP es un método no genérico y MQ es un método genérico, entonces MP es mejor que MQ". Supongo que alguna otra regla entra en juego primero, pero no estoy seguro de cuál. – Giles

+0

Lo sentimos, debería ser 7.5.3.2 "Mejor miembro de función". – Giles

Cuestiones relacionadas