2012-03-05 11 views
16

Olası Çoğalt: Peter p.TellYourAge() ve p.DoSomething() çağrısı değil neden İsteğe bağlı argümanlar ile C# 'un bu garip davranışını açıklayabilir misiniz?

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

Beni açıklayabilir:

C# optional parameters on overridden methods

Bu aşağıdaki kod çıkışı özdeş? Eğer Resharper kullanıyoruz edersek

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

Benim ilk tahminim int burada null olmadığından şudur: public override void TellYourAge (int yaş = -1) varsayılan değerle geçersiz //, varsayılan her zaman 0'dır var ... – mservidio

+2

@mservidio Ama işte bu yüzden varsayılan değeri belirtin –

+1

Bu makale ilginizi çekebilir [http://blogs.msdn.com/b/ericlippert/archive/2011/05/09/optional-argument-corner-cases-part-one. aspx) tarafından Eric Lippert. Tam olarak aynı davayı açıklamamasına rağmen, neler olduğu konusunda size bazı ipuçları vermelidir. –

cevap

3

, size aşağıdaki uyarı/bildirim verecektir: Burada

kod

(VS2010 ve FW 4) kendiniz denemek için.

"İsteğe bağlı parametre varsayılan değeri, taban yönteminde TellYourAge (int age) parametresindeki yaştan farklıdır."

İsteğe bağlı parametre değerlerini ve devralmayı karıştırdığınızda dikkatli olun. Varsayılan parametre değerleri çalışma zamanında değil derleme zamanında çözülür. Varsayılan, çağrılan referans türüne aittir. Burada Kişi türüne gider ve -1 yerine 0 olan bir tamsayı varsayılan değerini kullanır.

Burada isteğe bağlı parametreleri ile ilgili olarak ortak tuzaklar hakkında bazı bilgileri bulabilirsiniz:

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

Kolay düzeltme bunu bu şekilde kullanmak istiyorsanız. TellYourAge yöntemini çağırırken 'this' anahtar kelimesini açıkça belirtin. Bu şekilde istenen varsayılan değer derleme zamanında belirlenir.

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

Bu durumda bir derleme hatası veya uyarı beklerdim, ancak konu bu değil. Varsayılan parametrelerin derleme zamanında çözüldüğü de açıktır, ancak p'teki TellYourAge() öğesine yapılan aynı çağrının neden farklı çıktılarla sonuçlanacağını açıklamıyor. – X181

+0

Ayrıca bkz. Http://blogs.msdn.com/b/ericlippert/archive/2011/05/09/optional-argument-corner-cases-part-one.aspx –

+1

Konular konuyla ilgilidir, ancak bir kopyası değildir. Diğer durumda belirli bir varsayılan değer kullanılır. Bu durumda, türün belirtilmemiş varsayılan değeri kullanılır. – X181

İlgili konular