2013-04-30 18 views
94

Aşağıdaki kod sonuçları:Neden bu (null ||! TryParse) koşullu "atanmamış yerel değişkenin kullanımı" sonucunu verir?</em> atanmamış yerel değişken "numberOfGroups" nin <em>kullanımda

int numberOfGroups; 
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups)) 
{ 
    numberOfGroups = 10; 
} 

Ancak bu kod çalışıyor (gerçi, ReSharper= 10 gereksiz olduğunu söylüyor):

int numberOfGroups = 10; 
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups)) 
{ 
    numberOfGroups = 10; 
} 

Am Bir şey mi eksik, yoksa derleyici ||'umu beğenmiyor mu?

Bu soruna neden olarak dynamic nedenini daraltdım (options yukarıdaki kodumda dinamik bir değişkendi). Soru hala devam ediyor, neden bunu yapamıyorum?

internal class Program 
{ 
    #region Static Methods 

    private static void Main(string[] args) 
    { 
     dynamic myString = args[0]; 

     int myInt; 
     if(myString == null || !int.TryParse(myString, out myInt)) 
     { 
      myInt = 10; 
     } 

     Console.WriteLine(myInt); 
    } 

    #endregion 
} 

Ancak bu kod yapar:

internal class Program 
{ 
    #region Static Methods 

    private static void Main(string[] args) 
    { 
     var myString = args[0]; // var would be string 

     int myInt; 
     if(myString == null || !int.TryParse(myString, out myInt)) 
     { 
      myInt = 10; 
     } 

     Console.WriteLine(myInt); 
    } 

    #endregion 
} 

ben dynamic bu bir faktör olacağını fark etmedi

Bu kod derleme yapmaz.

+0

o kadar akıllı düşünmüyor musunuz:

Yapı Eric Lippert en repro kapalı, burada ne yol idam edilecek ve değişken başlangıç ​​değerine sahip olacak bir talebi gösterir kısa ve tam bir programdır – Charleh

+0

girdisi olarak 'out' parametresine iletilen değeri kullanmadığınızı bilmek, burada hata nedir? Gösterdiğiniz koddan sonra 'numberOfGroups' * kullanılıyor mu? Sorunu gösteren kısa ama eksiksiz bir programı göstermek için soruyu değiştirebilir misiniz? –

+3

Burada verilen kod açıklanan davranışı göstermez; Sadece iyi çalışıyor. Lütfen * aslında tanımladığınız davranışı gösteren * kendimizi derleyebileceğimiz bir kod yayınlayın. Bize tüm dosyayı ver. –

cevap

72

Bunun bir derleyici hatası olduğundan eminim. Güzel bul!

Düzenleme: Quartermeister'in gösterdiği gibi bir hata değildir; Dinamik, y'un hiçbir zaman başlatılmaması için garip bir true operatörünü uygulayabilir. İşte

minimal üreme var: Bunun yasadışı olmalıdır neden göremiyorum

class Program 
{ 
    static bool M(out int x) 
    { 
     x = 123; 
     return true; 
    } 
    static int N(dynamic d) 
    { 
     int y; 
     if(d || M(out y)) 
      y = 10; 
     return y; 
    } 
} 

; Eğer dinamik boole ile değiştirirseniz, o da iyi derler.

Aslında yarın C# takımıyla buluşacağım; Onlardan bahseteceğim. Hata için özür dilerim!

+6

Sadece delirmediğimi bildiğim için çok mutluyum :) Kodumu güncelledikten sonra sadece TryParse'e güveniyorum, bu yüzden şimdilik ayarlıyım. İçgörün için teşekkürler! –

+0

@EricLippert, bu bir hata mı, yoksa tasarım hatası mı? Cevabım belirttiği için derleyici, herhangi bir ifadeyi bir 'dinamik' değişkeniyle çözmek için * değil * tasarlandı. Belki de 'bool' vakasının ayrı ayrı ele alınması gerekiyordu? – NominSim

+0

@BrandonMartinez: Ya da, sadece yerel başlatmak. –

7

From MSDN (vurgu benim): derleyici kontrol etmek veya dinamik Çeşidi ifadelerini içeren tüm işlemleri çözmek tipi olmadığından

The dynamic type enables the operations in which it occurs to bypass compile-time type checking. Instead, these operations are resolved at run time. The dynamic type simplifies access to COM APIs such as the Office Automation APIs, and also to dynamic APIs such as IronPython libraries, and to the HTML Document Object Model (DOM).

Type dynamic behaves like type object in most circumstances. However, operations that contain expressions of type dynamic are not resolved or type checked by the compiler.

, bu değişken TryParse() kullanımı yoluyla atanacak garanti edemez.

+0

Eğer ilk koşul yerine getirilirse, 'numberGroups' atanır. “blok”, değilse, ikinci koşul, atama ('dışarıdan') garanti eder. – leppie

+1

Bu ilginç bir düşünce, * ama * kod, "myString == null" olmadan (yalnızca "TryParse" ye güvenmeksizin) derler. –

+1

@leppie Buradaki nokta, ilk koşul olduğundan (aslında tüm "if" ifadesi) bir "dinamik" değişkeni içerdiği için, derleme zamanında çözülmez (derleyici bu varsayımları yapamaz). – NominSim

51

Dinamik ifadenin değeri, aşırı yüklenmiş true operatör'un türüne sahipse, değişken atamasının kaldırılması mümkündür.

|| operatör sağ tarafını değerlendirmek için karar vermek true operatörü çağıracağı ve sonra if deyimi kendi vücudunu değerlendirmek için karar vermek true operatörü açılmasına neden olur. Normal bir bool için, bunlar her zaman aynı sonucu döndürecek ve tam olarak bir tane değerlendirilecektir, ancak kullanıcı tanımlı bir operatör için böyle bir garanti yoktur!

using System; 

class Program 
{ 
    static bool M(out int x) 
    { 
     x = 123; 
     return true; 
    } 

    static int N(dynamic d) 
    { 
     int y = 3; 
     if (d || M(out y)) 
      y = 10; 
     return y; 
    } 

    static void Main(string[] args) 
    { 
     var result = N(new EvilBool()); 
     // Prints 3! 
     Console.WriteLine(result); 
    } 
} 

class EvilBool 
{ 
    private bool value; 

    public static bool operator true(EvilBool b) 
    { 
     // Return true the first time this is called 
     // and false the second time 
     b.value = !b.value; 
     return b.value; 
    } 

    public static bool operator false(EvilBool b) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

Bu oldukça düzgün, ama OP'in davasına uygulandığından emin değilim, çünkü bir eşitlik operatörü çalıştırılıyor; Bu durumda özel bir 'operatör' doğru aramak için bir şans olduğunu sanmıyorum. – dlev

+0

@dlev: Eşitlik ifadesi de dinamik olarak bağlıdır ve 'bool' dışında bir şey döndüren kullanıcı tanımlı bir işleve bağlanabilir. – Quartermeister

+0

Hata! operator operatörü unuttum == '' bool' döndürmek zorunda değil. – dlev

İlgili konular