2012-03-05 21 views
16

Duplicar posible:
C# optional parameters on overridden methods¿Puede explicarme este comportamiento extraño de C# con argumentos opcionales?

Ésta es la salida del siguiente código:

Peter: -1 
Peter: 0 
Fred: 1 
Fred: 1 

¿Me puede explicar por qué la llamada de Pedro p.TellYourAge() y p.DoSomething() no es ¿idéntico?

Aquí el código de hacerlo por uno mismo (VS2010 y FW 4):

static void Main(string[] args) 
    { 
     Peter p = new Peter(); 
     p.TellYourAge(); // expected -1, result: -1 
     p.DoSomething(); // expected -1, result: 0 

     Fred f = new Fred(); 
     f.TellYourAge(1); // expected 1, result: 1 
     f.DoSomething(); // expected 1, result: 1 

     Console.ReadKey(); 
    } 
} 

public abstract class Person 
{ 
    public abstract void TellYourAge(int age); // abstract method without default value 
} 

public class Peter : Person 
{ 
    public override void TellYourAge(int age = -1) // override with default value 
    { 
     Console.WriteLine("Peter: " + age); 
    } 

    public void DoSomething() 
    { 
     TellYourAge(); 
    } 
} 

public class Fred : Person 
{ 
    public override void TellYourAge(int age) // override without default value 
    { 
     Console.WriteLine("Fred: " + age); 
    } 

    public void DoSomething() 
    { 
     TellYourAge(1); 
    } 
} 
+2

Mi primera suposición es que ya no es anulable int aquí: override public void TellYourAge (int edad = -1) // anular con el valor por defecto, que es por defecto es siempre 0 ... – mservidio

+2

@mservidio Pero es por eso especifica el valor predeterminado –

+1

Puede que le interese [este artículo] (http://blogs.msdn.com/b/ericlippert/archive/2011/05/09/optional-argument-corner-cases-part-one. aspx) por Eric Lippert. Aunque no describe exactamente el mismo caso, debería darte algunas pistas sobre lo que está sucediendo. –

Respuesta

3

Si usted usa ReSharper, se le dará el siguiente aviso/notificación.

"El valor predeterminado del parámetro opcional difiere de la edad del parámetro en el método base void TellYourAge (int age)."

Tenga cuidado al mezclar valores de parámetros opcionales y herencia. Los valores de parámetros predeterminados se resuelven en tiempo de compilación, no en tiempo de ejecución. El valor predeterminado pertenece al tipo de referencia que se llama. Aquí se resuelve en el tipo Persona y utiliza el valor predeterminado de un entero que es 0, en lugar de -1.

Puede encontrar información sobre los errores comunes en relación con los parámetros opcionales aquí:

http://geekswithblogs.net/BlackRabbitCoder/archive/2010/06/17/c-optional-parameters---pros-and-pitfalls.aspx

solución fácil si usted quiere usarlo de esta manera. Especifique explícitamente la palabra clave 'this' cuando llame al método TellYourAge. De esta forma, el valor predeterminado deseado se determinará en el momento de la compilación.

public void DoSomething() 
{ 
    this.TellYourAge(); 
} 
+1

Me esperaba un error de compilación o advertencia en este caso, pero ese no es el punto. El hecho de que los parámetros predeterminados se resuelvan en tiempo de compilación también es claro, pero no explica por qué la misma llamada a TellYourAge() en la p-instancia da como resultado una salida diferente. – X181

+0

Véase también http://blogs.msdn.com/b/ericlippert/archive/2011/05/09/optional-argument-corner-cases-part-one.aspx –

+1

Los temas están relacionados, pero no es un duplicado. En el otro caso, se usa un valor predeterminado especificado. En este caso, se utiliza el valor predeterminado no especificado del tipo. – X181

Cuestiones relacionadas