2012-02-16 4 views
6

Aquí está el código simple para un programa en C# 4.0 consola:C# 4.0 Compilar error de tiempo, no puede resolver la sobrecarga cuando la sobrecarga equivocada contiene tipos de parámetros definidos en los componentes .NET que no se hace referencia

using System.DirectoryServices.Protocols; 
namespace OverloadTest 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     var request = new SearchRequest("", "", SearchScope.Base, null); 
    } 
    } 
} 

SearchRequest tiene 3 constructors; solo los dos que toman 4 parámetros importan para este ejemplo:

Entre estos dos constructores, tienen parámetros escritos y nombrados de manera idéntica para sus parámetros primero, tercero y cuarto. Solo los segundos parámetros difieren: string ldapFilter versus XmlDocument filter.

El código anterior es, obviamente, para mí, llamando al constructor que tiene su segundo parámetro declarado como: cadena ldapFilter.

Pero si el proyecto que este es el código de NO tiene una referencia a System.XML luego un compilar los resultados en el siguiente error:
El tipo 'System.Xml.XmlDocument' se define en una asamblea que no está referenciado. Debe agregar una referencia al ensamblado 'System.XML, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089'

Al parecer, el compilador no puede evaluar qué sobrecargue de usar debido a la sobrecarga del mal tiene un parámetro de un tipo que no se entiende debido a la falta de referencia al componente de declaración. Claro, el compilador tiene que encontrar un "mejor método" para que coincida con mi código, pero como mi segundo parámetro pasado es cadena ¿por qué el compilador necesita preocuparse por la coincidencia de mi código con la sobrecarga XmlDocument? O alternativamente, como System.DirectoryServices.Protocols.SearchRequest está utilizando el tipo XmlDocument (como un tipo de parámetro de constructor); ¿Por qué el compilador ya no sabe lo suficiente sobre qué es un XmlDocument para determinar que una cadena no es una y así poder elegir la sobrecarga correcta?

ya tengo dos soluciones temporales que compilan sin errores:

  1. agregar una referencia a System.XML en el proyecto.

  2. Nombre del segundo parámetro (y así el tercero y cuarto también por necesidad), así:

    var request = new SearchRequest("", ldapFilter: "", searchScope: SearchScope.Base, attributeList: null); 
    

    Para mi caso particular, esto funciona porque el segundo parámetros las dos sobrecargas no sólo difieren en el tipo de sino también en nombre (ldapFilter versus filtro).

Sería bueno, aunque no fue necesario ningún tipo de solución.

+1

Aunque es interesante, voy a votar para cerrar porque esto parece poco más que una queja sobre la naturaleza de la resolución de dependencia. – spender

+0

Interesante encontrado. Creo que el compilador debe conocer la información de tipo de los parámetros de todos los métodos de sobrecarga para resolver cuál es el mejor. – findcaiyzh

+1

Nada mantiene al escritor de compilación en la noche como una resolución de sobrecarga de método no intencional. Este ejemplo está en la parte inferior de la pila. –

Respuesta

3

La segunda sobrecarga podría seguir siendo aplicable debido a una conversión implícita.

I piensa que en este caso, el string se elegiría siempre, porque coincide exactamente. Pero el algoritmo es probablemente más general y causa un error cuando cree que necesita saber qué tipo tiene exactamente esa otra sobrecarga.

Ejemplo de la situación problemática:

class A 
{} 

class B 
{ 
    public static implicit operator B(A a) 
    { 
     return null; 
    } 
} 

class C 
{ 
    public static implicit operator C(A a) 
    { 
     return null; 
    } 
} 

public static void M(B b) 
{} 

public static void M(C a) 
{} 

Aquí, tipos B y C son de diferentes conjuntos. Ahora, si llama al M(new A()), qué sobrecarga se elegiría podría depender de a qué conjuntos se hace referencia. Como tal comportamiento es indeseable, el compilador se da por vencido, para estar seguro.

Como dije, su muestra no es exactamente así, pero es probable que el compilador siga las mismas reglas.

+0

De acuerdo. Sin embargo, parece que la conversión implícita no debería importar si los parámetros pasados ​​coinciden exactamente con los tipos de una sobrecarga dada. Tal vez haya un escenario donde el algoritmo que es menos general no sería seguro; de ser así, sería interesante ver un ejemplo de eso. –

Cuestiones relacionadas