2010-09-02 11 views
6

Digamos que tengo una clase (ClassA) que contiene un método que llama al constructor de otra clase, de esta manera:¿Por qué estoy obligado a hacer referencia a los tipos en los constructores no utilizados?

public class ClassA 
{ 
    public void CallClassBConstructor() 
    { 
     using(ClassB myB = new ClassB()) {...} 
    } 
} 

La clase ClassB se parece a esto:

public class ClassB : IDisposable 
{ 
    public ClassB(){} 
    public ClassB(string myString){} 
    public ClassB(ClassC myC){} 
    public void Dispose() {...} 
} 

... y ClassC es aún más sencilla:

public class ClassC{} 

Si pongo estas clases en su propio culo embly y compila toda la solución no obtengo ningún error. Pero si se sustituye la instrucción using con esto:

using(ClassB myB = new ClassB("mystring")){...} 

me sale un error de compilación que me pide que agregar una referencia a [mynamespace].ClassC en ClassA. Ya que no estoy llamando al ClassB(ClassC myC) en absoluto, esto no tiene sentido para mí, ¿por qué tengo que incluir los tipos de otros constructores independientemente de si los uso o no? ¿Qué pasa si ClassC se incluyó en una asamblea con licencia o difícil de adquirir? ¿Es este un ejemplo de mal diseño que los desarrolladores deberían evitar o me falta algo aquí?

+3

Esto no puede compilar en primer lugar, ClassB no implementa IDisposable. Entonces no puede usarse en una cláusula de uso. –

+0

Esto no es C/C++ donde el código inválido no utilizado se ignorará silenciosamente si el engarce lo hace gc'd. – leppie

+0

He editado el código para que compile ahora –

Respuesta

9

Tiene que ver con la resolución de sobrecarga método cuando una llamada al constructor ClassB.

Cuando llama al constructor sin parámetros, no hay contienda. Solo hay un candidato, entonces es elegido. No es necesario que ClassA haga referencia a ClassC en este caso.

Sin embargo, cuando se llama al constructor con un parámetro, a continuación, desde el principio, tanto de los constructores de un solo parámetro son candidatos. Para resolver esta llamada, el compilador necesita saber acerca de ClassC. Por lo que usted sabe, ClassC podría contener un operador de conversión implícito, por ejemplo.

(Por supuesto, sabemos que en este ejemplo particular un operador de conversión implícito no se activaría porque hay una coincidencia perfecta que toma una cadena, pero las reglas de resolución de sobrecarga del método se definen de esta manera para que estén muy bien -definida y predecible. Imagínese que fueron diseñados de tal manera que la adición de una referencia podría hacer que su código para llamar a una sobrecarga de repente constructor diferente.)

+0

Gracias Timwi, creo que todas las respuestas me lo dejaron muy claro :-) –

+0

Cómo ¿viene una declaración 'using' que falta no es suficiente para que el compilador sepa qué sobrecarga usar? Estoy confundido de que simplemente agregar la referencia hace feliz al compilador. – Stijn

+0

@Stijn: Probablemente se refiera a la directiva ['using'] (http://msdn.microsoft.com/en-us/library/sf0df423.aspx), * not * a la [' using' statement] (http://msdn.microsoft.com/en-us/library/yh598w02.aspx). Pero aun así, ni la pregunta ni mi respuesta tienen nada que ver con las instrucciones 'using' o *' using'. Se trata de [referencias a otros ensamblados] (http://msdn.microsoft.com/en-us/library/wkze6zky%28v=vs.80%29.aspx). La declaración 'using' no agrega dicha referencia. – Timwi

1

Para resolver las sobrecargas del constructor, el compilador necesita conocer los tipos implicados. Es decir. necesita saber ClassC para elegir la sobrecarga derecha del constructor para ClassB.

+0

Gracias por su respuesta Brian - estuvo de acuerdo con las otras respuestas –

1

Es porque ClassC, que ha colocado en un conjunto separado, es parte de la interfaz pública de ClassB ya que es un parámetro de uno de los constructores. Debe hacer referencia al ensamblaje contenedor de este tipo; de lo contrario, el compilador no tiene idea de cómo resolver la información del tipo. En este caso específico, el compilador debe resolver todos los tipos de parámetros de todas las sobrecargas del constructor para que pueda elegir el correcto, pero este no es un problema de sobrecarga de miembros per se. Esto sucede cada vez que el compilador debe resolver la información del tipo. También puede ocurrir en los tipos de devolución.

+0

¿Por qué el voto a favor? Incluso antes de mi edición, esta respuesta no fue incorrecta. –

+0

Lamento que soy nuevo en stackoverflow pero no hice clic en nada, simplemente recargué la página. Tal vez es por eso que fue downvoted? –

+0

@boomshanka: No, no fue nada lo que hiciste. Alguien pensó que esta respuesta era incorrecta o más perjudicial que útil. Estoy detrás de mi respuesta. –

Cuestiones relacionadas