2012-05-11 16 views
10

Co, jeśli w ogóle, jest różnica między?C# Casting to a decimal

decimal d = (decimal) myDouble; 
decimal d = new decimal(myDouble); 
decimal d = Convert.ToDecimal(myDouble); 

Odpowiedz

8

Nie ma różnicy.Jeśli spojrzeć na źródła:

W dziesiętnych:

public static explicit operator decimal(double value) 
{ 
    return new decimal(value); 
}  

Konwersja:

public static decimal ToDecimal(float value) 
{ 
    return (decimal) value; 
} 

Więc w końcu wszyscy wezwanie new decimal(double).

+0

Ale może istnieć różnica między "(dziesiętną) wartością" a "nową dziesiętną (wartością)": pierwsza wywołuje wbudowany dwu-dziesiętny operator konwersji, podczas gdy drugi wywołuje przeciążenie konstruktora dziesiętnego. Oczywiście, kod natywny prawdopodobnie będzie taki sam, ale IL jest prawdopodobnie inny, a semantyka C# z pewnością jest inna. – phoog

+2

@phoog Nie ma różnicy między tymi dwoma. Nie ma "wbudowanego" operatora konwersji dwu-do-dziesiętnej, pierwsza metoda podana w odpowiedzi to ta, która jest wywoływana. Pierwszy sposób, w jaki podałeś tylko wywołania, to drugi sposób podania jednej metody w dół drzewa wywołań. – JKor

+0

@JKor Nie dostarczyłem żadnych sposobów; Po prostu komentuję. – phoog

4

Wszystkie one osiągają takie same wyniki. Jednak tutaj jest bardziej podziale wyjaśnienie:

  • Metoda 1 tworzy nową zmienną, która wyraźnie rzuca myDouble wpisać decimal. Kiedy rzucasz, mówisz, "Ten obiekt typu A jest w rzeczywistości obiektem typu B pochodnego od A lub operator castingu istnieje, by rzutować A na B."

  • Metoda 2 tworzy nową zmienną, która będzie konwertować myDouble do odpowiedniego typu (decimal) poprzez przeciążenie konstruktora. Kiedy wywołujesz konstruktora, mówisz: "Utwórz nowy obiekt na podstawie argumentów przekazanych do konstruktora."

  • Metoda 3 przetwarza dane typu podstawa (double) do innego typu danych bazowej (decimal). Kiedy używasz czegoś takiego jak Convert.ToDecimal(), mówisz, "Ten obiekt nie jest typu B, ale istnieje sposób, aby uczynić go obiektem typu B."

chodzi Convert MSDN stanowi:

sposób
  • Konwersja istnieje konwersji każdego typu podstawowego do każdej innej podstawy. Jednak faktyczna wykonywana operacja konwersji mieści się w trzech kategoriach:

  • Konwersja z typu na taką po prostu zwraca ten typ. Nie jest przeprowadzana żadna konwersja.

  • Konwersja, która nie może dać znaczącego wyniku, powoduje zgłoszenie wyjątku InvalidCastException. Nie jest przeprowadzana żadna konwersja. Wyjątek jest zgłaszany dla konwersji z Char do Boolean, Single, Double, Decimal lub DateTime, a od tych typów Char. Wyjątek jest zgłaszany dla konwersji z DateTime do dowolnego typu z wyjątkiem String i dowolnego typu, z wyjątkiem ciągu String, do DateTime. Każdy rodzaj bazy, inny niż opisany powyżej, może być konwertowany na i z dowolnego innego typu podstawowego.
+0

Przykład 2 pokazuje przeciążenie konstruktora. Również przykład rzucony w przykładzie 1 nie jest rzutem zgodnie z twoją definicją, ponieważ przecinek dziesiętny nie pochodzi z podwójnego (ani odwrotnie). Zamiast tego operator rzutowania C# ma dwie funkcje: (1) zachowywanie rzutowania typów referencyjnych z zachowaniem reprezentacji i (2) wywoływanie wbudowanych lub zdefiniowanych przez użytkownika jawnych (lub niejawnych) konwersji. – phoog

3

Z funkcjonalnego punktu widzenia nie ma żadnej różnicy. Są to różne sposoby uzyskania osiągnięcia tego samego wyniku.

Ważne jest, że w przypadku Convert.ToDecimal masz możliwość określenia formatu IFormatProvider (kultura), dzięki czemu zyskujesz większą elastyczność.

Jeśli nie interesuje Cię środowisko wielokulturowe, wybierz dowolne z nich.

+1

Przypuszczam, że IFormatProvider jest tutaj ignorowany, ponieważ ani dane wejściowe, ani dane wyjściowe nie są ciągami. – phoog

+0

tak, poprawne. Nota dotyczyła ogólnej możliwej różnicy w użyciu – Tigran