C#中explicit與implicit的深入理解
前言
今天在研究公司項(xiàng)目框架的時(shí)候看到了下面的用法,public static implicit operator JsonData(int data); 。貌似很久沒(méi)用過(guò)這種隱式轉(zhuǎn)換的寫法了,因此重新溫習(xí)一下C#中轉(zhuǎn)換相關(guān)的知識(shí)。
explicit 和 implicit 屬于轉(zhuǎn)換運(yùn)算符,如用這兩者可以讓我們自定義的類型支持相互交換
explicti 表示顯式轉(zhuǎn)換,如從 A -> B 必須進(jìn)行強(qiáng)制類型轉(zhuǎn)換(B = (B)A)
implicit 表示隱式轉(zhuǎn)換,如從 B -> A 只需直接賦值(A = B)
implicit
implicit 關(guān)鍵字用于聲明隱式的用戶自定義的類型轉(zhuǎn)換運(yùn)算符。 如果可以確保轉(zhuǎn)換過(guò)程不會(huì)造成數(shù)據(jù)丟失,則可使用該關(guān)鍵字在用戶定義類型和其他類型之間進(jìn)行隱式轉(zhuǎn)換。
使用隱式轉(zhuǎn)換操作符之后,在編譯時(shí)會(huì)跳過(guò)異常檢查,所以隱式轉(zhuǎn)換運(yùn)算符應(yīng)當(dāng)從不引發(fā)異常并且從不丟失信息,否則在運(yùn)行時(shí)會(huì)出現(xiàn)一些意想不到的問(wèn)題。
示例
class Digit
{
 public Digit(double d) { val = d; }
 public double val;
 // ...other members
 // User-defined conversion from Digit to double
 public static implicit operator double(Digit d)
 {
  return d.val;
 }
 // User-defined conversion from double to Digit
 public static implicit operator Digit(double d)
 {
  return new Digit(d);
 }
}
class Program
{
 static void Main(string[] args)
 {
  Digit dig = new Digit(7);
  //This call invokes the implicit "double" operator
  double num = dig;
  //This call invokes the implicit "Digit" operator
  Digit dig2 = 12;
  Console.WriteLine("num = {0} dig2 = {1}", num, dig2.val);
  Console.ReadLine();
 }
}
隱式轉(zhuǎn)換可以通過(guò)消除不必要的強(qiáng)制轉(zhuǎn)換來(lái)提高源代碼的可讀性。 但是,因?yàn)殡[式轉(zhuǎn)換不需要程序員將一種類型顯式強(qiáng)制轉(zhuǎn)換為另一種類型,所以使用隱式轉(zhuǎn)換時(shí)必須格外小心,以免出現(xiàn)意外結(jié)果。 一般情況下,隱式轉(zhuǎn)換運(yùn)算符應(yīng)當(dāng)從不引發(fā)異常并且從不丟失信息,以便可以在程序員不知曉的情況下安全使用它們。 如果轉(zhuǎn)換運(yùn)算符不能滿足那些條件,則應(yīng)將其標(biāo)記為 explicit。 有關(guān)詳細(xì)信息,請(qǐng)參閱使用轉(zhuǎn)換運(yùn)算符。
explicit顯示轉(zhuǎn)換
explicit 關(guān)鍵字聲明必須通過(guò)顯示的調(diào)用用戶定義的類型轉(zhuǎn)換運(yùn)算符來(lái)進(jìn)行轉(zhuǎn)換。
以下示例定義從 Fahrenheit 類轉(zhuǎn)換為 Celsius 類的運(yùn)算符。 必須在 Fahrenheit 類或 Celsius 類中定義運(yùn)算符:
public static explicit operator Celsius(Fahrenheit fahr)
{
 return new Celsius((5.0f / 9.0f) * (fahr.Degrees - 32));
}
如下所示,調(diào)用用戶定義的轉(zhuǎn)換運(yùn)算符來(lái)強(qiáng)制轉(zhuǎn)換:
Fahrenheit fahr = new Fahrenheit(100.0f);
Console.Write($"{fahr.Degrees} Fahrenheit");
Celsius c = (Celsius)fahr;
此轉(zhuǎn)換運(yùn)算符從源類型轉(zhuǎn)換為目標(biāo)類型。 源類型提供轉(zhuǎn)換運(yùn)算符。 不同于隱式轉(zhuǎn)換,顯式轉(zhuǎn)換運(yùn)算符必須通過(guò)轉(zhuǎn)換的方式來(lái)調(diào)用。 如果轉(zhuǎn)換操作會(huì)導(dǎo)致異?;騺G失信息,則應(yīng)將其標(biāo)記為 explicit。 這可阻止編譯器靜默調(diào)用可能產(chǎn)生意外后果的轉(zhuǎn)換操作。
省略轉(zhuǎn)換將導(dǎo)致編譯時(shí)錯(cuò)誤 CS0266。
有關(guān)詳細(xì)信息,請(qǐng)參閱使用轉(zhuǎn)換運(yùn)算符。
示例
下面的示例提供了 Fahrenheit 和 Celsius 類,其中每個(gè)類均提供轉(zhuǎn)換為其他類的顯式轉(zhuǎn)換運(yùn)算符。
class Celsius
{
 public Celsius(float temp)
 {
  Degrees = temp;
 }
 
 public float Degrees { get; }
 
 public static explicit operator Fahrenheit(Celsius c)
 {
  return new Fahrenheit((9.0f / 5.0f) * c.Degrees + 32);
 }
}
class Fahrenheit
{
 public Fahrenheit(float temp)
 {
  Degrees = temp;
 }
 
 public float Degrees { get; }
 
 public static explicit operator Celsius(Fahrenheit fahr)
 {
  return new Celsius((5.0f / 9.0f) * (fahr.Degrees - 32));
 }
}
class MainClass
{
 static void Main()
 {
  Fahrenheit fahr = new Fahrenheit(100.0f);
  Console.Write($"{fahr.Degrees} Fahrenheit");
  Celsius c = (Celsius)fahr;
  Console.Write($" = {c.Degrees} Celsius");
  Fahrenheit fahr2 = (Fahrenheit)c;
  Console.WriteLine($" = {fahr2.Degrees} Fahrenheit");
 }
}
// 輸出:
// 100 Fahrenheit = 37.77778 Celsius = 100 Fahrenheit
示例
下面的示例定義結(jié)構(gòu) Digit,它表示單個(gè)的十進(jìn)制數(shù)字。 將運(yùn)算符定義為從 byte 到 Digit 的轉(zhuǎn)換,但由于并非所有字節(jié)都可轉(zhuǎn)換為 Digit,因此該轉(zhuǎn)換應(yīng)該應(yīng)用顯式轉(zhuǎn)換。
struct Digit
{
 byte value;
 public Digit(byte value)
 {
  if (value > 9)
  {
   throw new ArgumentException();
  }
  this.value = value;
 }
 // 定義從byte到Digit的顯示轉(zhuǎn)換 explicit operator:
 public static explicit operator Digit(byte b)
 {
  Digit d = new Digit(b);
  Console.WriteLine("轉(zhuǎn)換已完成");
  return d;
 }
}
class ExplicitTest
{
 static void Main()
 {
  try
  {
   byte b = 3;
   Digit d = (Digit)b; // 顯示轉(zhuǎn)換
  }
  catch (Exception e)
  {
   Console.WriteLine("{0} 捕獲到一成.", e);
  }
 }
}
/*
輸出:
轉(zhuǎn)換已完成
*/
參考資料
- explicit
 - operator (C# Reference)
 - How to: Implement User-Defined Conversions Between Structs
 - implicit
 
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)我們的支持。
上一篇:C#如何使用Bogus創(chuàng)建模擬數(shù)據(jù)示例代碼
欄 目:C#教程
下一篇:C#利用緩存分塊讀寫大文件
本文標(biāo)題:C#中explicit與implicit的深入理解
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/4766.html
您可能感興趣的文章
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并打開的方法
 - 01-10C#通過(guò)重寫Panel改變邊框顏色與寬度的方法
 - 01-10C#實(shí)現(xiàn)Winform中打開網(wǎng)頁(yè)頁(yè)面的方法
 - 01-10C#實(shí)現(xiàn)實(shí)體類與字符串互相轉(zhuǎn)換的方法
 - 01-10C#實(shí)現(xiàn)由四周向中心縮小的窗體退出特效
 - 01-10Extjs4如何處理后臺(tái)json數(shù)據(jù)中日期和時(shí)間
 - 01-10C#中DataGridView常用操作實(shí)例小結(jié)
 - 01-10C#編程獲取資源文件中圖片的方法
 - 01-10asp.net中XML如何做增刪改查操作
 - 01-10C#利用反射技術(shù)實(shí)現(xiàn)去掉按鈕選中時(shí)的邊框效果
 


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
 - 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
 - 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
 - 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
 - 5c語(yǔ)言計(jì)算三角形面積代碼
 - 6什么是 WSH(腳本宿主)的詳細(xì)解釋
 - 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
 - 8正則表達(dá)式匹配各種特殊字符
 - 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
 - 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
 
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
 - 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開的解決方案
 - 01-10WinForm限制窗體不能移到屏幕外的方法
 - 01-10WinForm繪制圓角的方法
 - 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
 - 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
 - 01-10C#停止線程的方法
 - 01-10C#實(shí)現(xiàn)清空回收站的方法
 - 01-10C#通過(guò)重寫Panel改變邊框顏色與寬度的
 - 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
 
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
 - 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
 - 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
 - 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
 - 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
 - 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
 - 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
 - 01-10C#中split用法實(shí)例總結(jié)
 - 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
 - 01-10delphi制作wav文件的方法
 


