2012-08-14 14 views
8

Ho un personalizzato WebControl che implementa una .Value getter/incastonatore di restituire un Nullable <decimale>Capire l'operatore null coalescenza (??)

E 'una casella di testo filtrata sul lato client (una sottoclasse di TextBox con incluso javascript e una logica lato server per l'impostazione/ottenere il valore)

Ecco il getter & il setter da quella di controllo:

public decimal? Value 
{ 
    get 
    { 
     decimal amount = 0; 
     if (!decimal.TryParse(this.Text, NumberStyles.Currency, null, out amount)) 
     { 
      return null; 
     } 
     else 
     { 
      return amount; 
     } 
    } 
    set 
    { 
     if (!value.HasValue) 
     { 
      this.Text = ""; 
     } 
     else 
     { 
      this.Text = string.Format("${0:#,##0.00}", value); 
     } 
    } 
} 

Il problema che sto vedendo è che l'uscita da questa affermazione:

decimal Amount = uxAmount.Value ?? 0M; 

sto vedendo Importo di essere impostato su "0" quando uxAmount.Value restituisce 10000.

questo ha funzionato come mi aspettavo (scusa la variazione di cassa):

decimal? _Amount = uxAmount.Value; 
decimal amount = _Amount ?? 0; 

ho visto anche questo comportamento (di recente) quando si chiama una funzione UDF definita in un contesto dati Linq2Sql insieme con l'operatore null coalescenza, ovvero sapevo che la mia chiamata UDF restituito il previsto valore ma ero ge invece il valore RHS.

Inoltre confondermi, se valuto uxAmount.Value nell'orologio, ottengo 10000 di tipo Nullable<decimal>.

Qui ci sono alcune espressioni che ho provato:

decimal? _Amount = uxAmount.Value; //10000 
decimal amount = _Amount ?? 0; //10000 
decimal amount2 = _Amount ?? 0M; //10000 
decimal Amount = uxAmount.Value ?? 0M; //0 

poi ho aggiunto questa espressione a seguito del già 4

decimal amount3 = (uxTaxAmount.Value) ?? 0M; 

Ora

decimal Amount = uxAmount.Value ?? 0M; //10000 
decimal amount3 = (uxAmount.Value) ?? 0M; //0 

Sembra che l'ultima chiamata è sempre 0, ma il valore di uxAmount.Value (che viene analizzato da .Text come sopra getter/setter usando TryParse è stabile. Mi fermo a un punto di interruzione e non ci sono altri thread in grado di manipolare questo valore.

Si noti l'uso del suffisso M per imporre la costante al decimale come se fosse intero e ho il sospetto di un problema di conversione del tipo.

Qualche idea?

Il valore di LHS e RHS sembra essere stabile e noto.

--edit-- alcuni screengrabs da VS2010

Stepping through the code showing the value of amount3

Watch dialog and some more detail about state of variables

+0

CurrencyTextBox (una sottoclasse di TextBox) – agrath

+1

È un decimale nullable [decimale?] - vedere la definizione getter/setter nella parte superiore della domanda – agrath

+1

Sei sicuro che il debugger lo visualizzi correttamente? Hai provato a calpestare alcune righe per assicurarti di avere il valore aggiornato di 'amount3'? Perché quando 'XXX' è un decimale annullabile, allora' XXX ?? 0M' sarà un decimale (non annullabile) che avrà il valore di 'XXX' se non è nulla, e il valore zero altrimenti. –

risposta

0

(La risposta è stata costruita dai miei commenti sopra.)

Sei sicuro che il dsiplays debugger correttamente questo per te? Hai provato a fare qualche passo più in basso per assicurarti di avere il valore aggiornato di amount3?

Sono sicuro che è solo un problema con il debugger. A volte devi andare un po 'oltre. Forse il codice tradotto (IL) ha alcune ottimizzazioni che confondono il debugger (o cosa dovrei sapere). Ma senza il debugger, il valore verrà aggiornato esattamente quando te lo aspetti.

Ho visto altri sviluppatori esperti essere confusi da situazioni simili, quindi so che il debugger a volte è "una riga di codice" dietro quando si guarda un'assegnazione a una variabile locale. Forse qualcuno può trovare un link per discuterne?

1

Date un'occhiata a questa domanda simile

using coalescing null operator on nullable types changes implicit type

perché non basta fare

decimal amount = uxTaxAmount.Value.HasValue ? uxTaxAmount.Value.Value : 0M 

Questa non è la risposta giusta ai problemi dei poster originali dati recenti modifiche e commenti.

+0

Si scopre che si tratta di un problema di debugger.Ero molto preoccupato del fatto che il mio uso di ?? aveva un sacco di effetti collaterali sconosciuti e avrei dovuto esaminare tutti i miei progetti e assicurarmi di aver modificato la sintassi – agrath

+0

Inoltre, .Value è decimale? (Nullable ) – agrath

+0

oh non ho fatto quella connessione, poiché è un decimale nullable il valore effettivo sarebbe Value.Value :) –