標籤:你知道 變數 font 文法 name 範圍 tin ros 轉換
使用者定義的資料類型轉換
C#允許定義自己的 資料類型,這意味著需要某些 工具支援在自己的資料類型間進行資料轉換.方法是把資料類型轉換定義為相關類的一個成員運算子,資料類型轉換必須聲明為隱式或者顯式,以說明怎麼使用它.
C#允許使用者進行兩種定義的資料類型轉換,顯式和隱式,顯式要求在代碼中顯式的標記轉換,其方法是在原括弧中寫入目標資料類型.
對於預定義的資料類型,當資料類型轉換時可能失敗或者資料丟失,需要顯示轉換:
1.把int數值轉換成short時,因為short可能不夠大,不能包含轉換的數值.
2.把所有符號的資料轉換為無符號的資料,如果有符號的變數包含一個負值,會得到不正確的結果.
3.把浮點數轉換為整數資料類型時,數位小數部分會丟失.
此時應在代碼中進行顯示資料類型轉換,告訴編譯器你知道這會有遺失資料的危險,因此編寫代碼時把這些可能考慮在內.
注意:如果來源資料值使資料轉換失敗,或者可能會拋出異常,就應把資料類型轉換定義為顯式.
定義資料類型轉換的文法有點類似於運算子多載.
例如:隱式類型轉換的代碼:
public static inplicit operator float(Current current)
{}
和運算子多載相同,資料類型轉換必須聲明為public和static.
注意:
當資料類型轉換聲明為隱式時,編譯器可以顯式或隱式的調用資料類型轉換.
當資料類型轉換聲明為顯式的,編譯器只能顯式的調用類型轉換.
案例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 類型轉換
{
class Program
{
static void Main(string[] args)
{
try
{
Current balance = new Current(50, 35);
Console.WriteLine(balance);
Console.WriteLine("balance using tostring() : + " + balance.ToString());
//隱式類型轉換
float balance2 = balance;
Console.WriteLine("After converting to float : " + balance2);
//顯示類型轉換
balance = (Current)balance2;
Console.WriteLine("After converting to Current : " + balance);
float t = 45.63f;
Current c = (Current)t;
Console.WriteLine(c.ToString());
checked
{
balance = (Current)(-50.5);
Console.WriteLine("result is : " + balance.ToString());
}
}
catch (Exception)
{
Console.WriteLine("錯誤");
}
Console.ReadKey();
}
}
struct Current
{
public uint Dollars;
public ushort Cents;
//建構函式
public Current(uint dollars, ushort cents)
{
this.Dollars = dollars;
this.Cents = cents;
}
//重寫ToString()方法
public override string ToString()
{
return string.Format("{0}.{1,-2:00}", this.Dollars, this.Cents);
}
//隱式類型轉換
public static implicit operator float(Current value)
{
return value.Dollars + (value.Cents / 100.0f);
}
//顯示類型轉換
public static explicit operator Current(float f)
{
uint dollars = (uint)f;
ushort cents = (ushort)((f - dollars) * 100);
return new Current(dollars, cents);
}
}
}
將設計兩個問題:
1.從float轉換為Current得到錯誤的結果50.34,而不是50.35,----圓整造成的,發生截斷問題.
答:如果float值轉換為uint值,電腦就會截斷多餘的數字,而不是去圓整它.電腦資料是通過 二進位儲存的,而不是十進位,小數部分0.35不能以二進位形式儲存.因為捨棄一部分,故實際轉換成的資料要小於0.35,即可以用二進位形式儲存的值,然後數字乘以100,得到小於35的數字34,有時候這種階段是很危險的,避免這種錯誤的方式時確保在數字轉換過程中執行智能圓整操作.
Microsoft編寫了一個類System.Convert來完成該任務.System.Convert包含大量的靜態方法來執行各種數字轉換,我們要使用的是Convert.ToUint16().注意,在使用System.Convert方法會產生額外的效能損耗,所以只有在需要的時候才使用.
注意:System.Convert方法還執行他們自己的溢出檢查,所以
Convert.ToUint16((f-dollars)*100);
這樣的代碼可以不放在checked裡面.
2.在試圖轉換超出範圍的值時,沒有發生異常.主要是因為:發生溢出的位置根本不在Main常式中--這是在轉換運算子的代碼中發生的,該代碼在Main()方法中調用,該方法沒有標記為checked,其解決方案:
代碼:
public static explicit operator Current(float f)
{
checked
{
uint dollars = (uint)f;
ushort cents = Convert.ToUInt16((f - dollars) * 100);
return new Current(dollars, cents);
}
}
explicit和implicit屬於轉換運算子,乳癰這兩者可以讓我們自訂的類型支援相互交換
explicit表示顯示轉換,從A->B必須進行強制類型轉換:B=(B)A
implicit表示隱式轉換,如從B->A只需要直接複製A=B
隱式轉換可以讓我們的代碼看上去更漂亮,更簡潔移動,所以最好多使用implicit運算子.不過,如果對象本身在轉換時會損失一些資訊(如精度),那麼我們只能使用explicit運算子,以便在編譯期就能警告客戶調用.
C#編程(四十一)----------使用者定義的資料類型轉換