c#之用戶定義的數(shù)據(jù)類型轉(zhuǎn)換介紹
c# 允許用戶進(jìn)行兩種定義的數(shù)據(jù)類型轉(zhuǎn)換,顯式和隱式,顯式要求在代碼中顯式的標(biāo)記轉(zhuǎn)換,其方法是在圓括號(hào)中寫入目標(biāo)數(shù)據(jù)類型。
對(duì)于預(yù)定義的數(shù)據(jù)類型,當(dāng)數(shù)據(jù)類型轉(zhuǎn)換時(shí)可能失敗或丟失某些數(shù)據(jù),需要顯式轉(zhuǎn)換,
1 把int數(shù)值轉(zhuǎn)換成short時(shí),因?yàn)閟hort可能不夠大,不能包含轉(zhuǎn)換的數(shù)值。
2 把有符號(hào)的數(shù)據(jù)轉(zhuǎn)換為無符號(hào)的數(shù)據(jù),如果有符號(hào)的變量包含一個(gè)負(fù)值,會(huì)得到不正確的結(jié)果。
3 把浮點(diǎn)數(shù)轉(zhuǎn)換為整數(shù)數(shù)據(jù)類型時(shí),數(shù)字的小數(shù)部分會(huì)丟失。
此時(shí)應(yīng)在代碼中進(jìn)行顯式數(shù)據(jù)類型,因此編寫代碼時(shí)套把這些可能考慮在內(nèi)。
c#允許定義自己的數(shù)據(jù)類型,這意味著需要某些工具支持在自己的數(shù)據(jù)類型間進(jìn)行數(shù)據(jù)轉(zhuǎn)換。方法是把數(shù)據(jù)類型轉(zhuǎn)換定義為相關(guān)類的一個(gè)成員運(yùn)算符,數(shù)據(jù)類型轉(zhuǎn)換必須聲明是隱式或者顯式,以說明怎么使用它。
注意:如果源數(shù)據(jù)值使數(shù)據(jù)轉(zhuǎn)換失敗,或者可能會(huì)拋出異常,就應(yīng)把數(shù)據(jù)類型轉(zhuǎn)換定義為顯式。
定義數(shù)據(jù)類型轉(zhuǎn)換的語法類似于運(yùn)算符重載。
例如 :隱式類型轉(zhuǎn)換:
public static implicit operator float(Current current)
{
}
和運(yùn)算符重載相同,數(shù)據(jù)類型轉(zhuǎn)換必須聲明為public和static。
注意:
當(dāng)數(shù)據(jù)類型轉(zhuǎn)換聲明為隱式時(shí),編譯器可以顯式或者隱式的調(diào)用數(shù)據(jù)類型轉(zhuǎn)換。
當(dāng)數(shù)據(jù)類型轉(zhuǎn)換聲明為顯式時(shí),編譯器只能顯式的調(diào)用類型轉(zhuǎn)換。
下面是個(gè)小例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 類型轉(zhuǎn)換
{
struct Current
{
public uint Dollars;
public ushort Cents;
public Current(uint dollars, ushort cents)
{
this.Dollars = dollars;
this.Cents = cents;
}
public override string ToString()
{
return string.Format("{0}.{1,-2:00}",Dollars,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);
}
}
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 (System.Exception ex)
{
Console.WriteLine("Exception occurred:" + ex.Message);
}
Console.ReadKey();
}
}
}
將涉及到兩個(gè)問題:
1 從float轉(zhuǎn)換為Current得到錯(cuò)誤的結(jié)果50.34,而不是50.35.----圓整造成的....發(fā)生截?cái)鄦栴}。
答:如果float值轉(zhuǎn)換為uint值,計(jì)算機(jī)就會(huì)截?cái)喽嘤嗟臄?shù)字,而不是去圓整它。計(jì)算機(jī)中數(shù)據(jù)是通過二進(jìn)制存儲(chǔ)的,而不是十進(jìn)制,小數(shù)部分0.35不能以二進(jìn)制形式儲(chǔ)存。因?yàn)樯釛壱徊糠?,故?shí)際轉(zhuǎn)化成的數(shù)據(jù)要小于0.35,即可以用二進(jìn)制形式存儲(chǔ)的值,然后數(shù)字乘以100,得到小于35的數(shù)字34.有時(shí)候這種階段是很危險(xiǎn)的,避免這種錯(cuò)誤的方式時(shí)確保在數(shù)字轉(zhuǎn)換過程中執(zhí)行智能圓整操作。
Microsoft編寫了一個(gè)類System.Covert來完成該任務(wù)。System.Covert包含大量的靜態(tài)方法來執(zhí)行各種數(shù)字轉(zhuǎn)換,我們要使用的是Convert.ToUInt16()。注意,在使用System.Covert方法產(chǎn)生額外的性能損耗,所以只有在需要的時(shí)候才使用。
注意: System.Covert方法還執(zhí)行他們自己的溢出檢查,所以
Convert.ToUInt16((f - dollars) * 100);
可以不放在checked里面.
2 在試圖轉(zhuǎn)換超出范圍的值時(shí),沒有發(fā)生異常。主要是因?yàn)椋喊l(fā)生溢出的位置根本就不在Main例程中--這是在轉(zhuǎn)換運(yùn)算符的代碼中發(fā)生的,改代碼在Main()方法中調(diào)用,該方法沒有標(biāo)記為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);
}
}<SPAN style="FONT-FAMILY: Arial, Verdana, sans-serif">
</SPAN>
相關(guān)文章
unity AudioSource播放完聲音后要執(zhí)行的函數(shù)或條件操作
這篇文章主要介紹了unity AudioSource播放完聲音后要執(zhí)行的函數(shù)或條件操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04C#實(shí)現(xiàn)對(duì)AES加密和解密的方法
C#實(shí)現(xiàn)對(duì)AES加密和解密的方法,需要的朋友可以參考一下2013-04-04