2012-08-14 23 views
8

I zwyczaj WebControl który implementuje .Value gettera/pobierz przekazujących pustych < dziesiętny >Zrozumienie zerowy operatora koalescencyjny (??)

to jest po stronie klienta filtrowanego tekstowe (podklasa TextBox pomocą dołączonego JavaScript i niektóre logiki po stronie serwera do ustawiania/uzyskiwania wartości)

Oto getter & setter z tej kontroli:

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); 
     } 
    } 
} 

Problem, który widzę jest, że wyjście z tego rachunku:

decimal Amount = uxAmount.Value ?? 0M; 

widzę ilość jest ustawiony na „0”, gdy uxAmount.Value powraca 10000.

To działało jak się spodziewałem (usprawiedliwienia zmiana obudowy):

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

widziałem też takiego zachowania (ostatnio) podczas wywoływania funkcji UDF zdefiniowany w kontekście danych linq2sql razem z zerowej operatora koalescencyjnego, to wiedziałem, moje wezwanie UDF zwrócił oczekiwano wartość, ale byłem ge zamiast tego wartość RHS.

Dalsze mylenie mnie, jeśli oceniam uxAmount.Value w zegarku, otrzymuję 10000 z typu Nullable<decimal>.

Oto niektóre wyrażenia próbowałem:

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

Potem dodałem tego wyrażenia po dokonaniu wspomnianej 4

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

Teraz

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

Wydaje się ostatniego połączenia jest zawsze 0, ale wartość uxAmount.Value (która jest przetwarzana z .Text jak na powyższy program pobierający/ustawiający przy użyciu TryParse jest stabilny. Zatrzymałem się w punkcie przerwania i nie ma innych wątków, które mogłyby manipulować tą wartością.

Zwróć uwagę na użycie przyrostka M, aby wymusić stałą dziesiętną, ponieważ była ona liczbą całkowitą i podejrzewałem problem z konwersją typu.

Wszelkie pomysły?

Wartość zarówno LHS, jak i RHS wydaje się być stabilna i znana.

--edit-- kilka screengrabs z VS2010

Stepping through the code showing the value of amount3

Watch dialog and some more detail about state of variables

+0

CurrencyTextBox (podklasa TextBox) – agrath

+1

Jest to dziesiętna zgrubna [dziesiętna?] - zobacz definicję gettera/settera u góry pytania – agrath

+1

Czy jesteś pewien, że debugger poprawnie to pokazuje? Czy próbowałeś przejść przez kolejne linie, aby upewnić się, że masz zaktualizowaną wartość "amount3"? Ponieważ gdy 'XXX' jest dziesiętnym z możliwością odgrodzenia, to' XXX ?? 0M' będzie (nie-nullowalnym) znakiem dziesiętnym, który będzie miał wartość "XXX", jeśli jest to wartość inna niż null, a wartość zero w przeciwnym razie. –

Odpowiedz

0

(Ta odpowiedź została wykonana z moich uwag powyżej).

Czy na pewno dsiplays debugger to poprawnie do ciebie? Czy próbowałeś przejść przez kolejne linie, aby upewnić się, że masz zaktualizowaną wartość amount3?

Jestem pewien, że to tylko problem z debuggerem. Czasami trzeba pójść trochę dalej. Może przetłumaczony kod (IL) ma pewne optymalizacje, które mylą debuggera (lub co ja wiem). Ale bez debuggera, wartość zostanie zaktualizowana dokładnie wtedy, gdy tego oczekujesz.

Widziałem, jak inni doświadczeni programiści są zdezorientowani podobnymi sytuacjami, więc wiem, że debugger czasami jest "jednym wierszem kodu", patrząc na przypisanie zmiennej lokalnej. Może ktoś może znaleźć link omawiający to?

1

Spójrz na tym podobnym pytaniem

using coalescing null operator on nullable types changes implicit type

dlaczego nie zrobić

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

To nie jest właściwa odpowiedź na oryginalne problemy z plakatem, z uwagi na ostatnie zmiany i komentarze.

+0

Okazuje się, że jest to problem z debugowaniem.Byłem bardzo zaniepokojony, że moje wykorzystanie? Miał wiele nieznanych skutków ubocznych i musiałbym przejrzeć wszystkie moje projekty i upewnić się, że zmieniono składnię. – agrath

+0

Również .Value jest dziesiętna? (Nullable) – agrath

+0

oh nie zrobiłem tego połączenia, ponieważ jego wartość dziesiętna zerowa wartość rzeczywista byłaby Value.Value :) –