C#中explicit與implicit的深入理解
前言
今天在研究公司項目框架的時候看到了下面的用法,public static implicit operator JsonData(int data); 。貌似很久沒用過這種隱式轉(zhuǎn)換的寫法了,因此重新溫習(xí)一下C#中轉(zhuǎn)換相關(guān)的知識。
explicit 和 implicit 屬于轉(zhuǎn)換運算符,如用這兩者可以讓我們自定義的類型支持相互交換
explicti 表示顯式轉(zhuǎn)換,如從 A -> B 必須進行強制類型轉(zhuǎn)換(B = (B)A)
implicit 表示隱式轉(zhuǎn)換,如從 B -> A 只需直接賦值(A = B)
implicit
implicit 關(guān)鍵字用于聲明隱式的用戶自定義的類型轉(zhuǎn)換運算符。 如果可以確保轉(zhuǎn)換過程不會造成數(shù)據(jù)丟失,則可使用該關(guān)鍵字在用戶定義類型和其他類型之間進行隱式轉(zhuǎn)換。
使用隱式轉(zhuǎn)換操作符之后,在編譯時會跳過異常檢查,所以隱式轉(zhuǎn)換運算符應(yīng)當(dāng)從不引發(fā)異常并且從不丟失信息,否則在運行時會出現(xià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)換可以通過消除不必要的強制轉(zhuǎn)換來提高源代碼的可讀性。 但是,因為隱式轉(zhuǎn)換不需要程序員將一種類型顯式強制轉(zhuǎn)換為另一種類型,所以使用隱式轉(zhuǎn)換時必須格外小心,以免出現(xiàn)意外結(jié)果。 一般情況下,隱式轉(zhuǎn)換運算符應(yīng)當(dāng)從不引發(fā)異常并且從不丟失信息,以便可以在程序員不知曉的情況下安全使用它們。 如果轉(zhuǎn)換運算符不能滿足那些條件,則應(yīng)將其標(biāo)記為 explicit。 有關(guān)詳細(xì)信息,請參閱使用轉(zhuǎn)換運算符。
explicit顯示轉(zhuǎn)換
explicit 關(guān)鍵字聲明必須通過顯示的調(diào)用用戶定義的類型轉(zhuǎn)換運算符來進行轉(zhuǎn)換。
以下示例定義從 Fahrenheit 類轉(zhuǎn)換為 Celsius 類的運算符。 必須在 Fahrenheit 類或 Celsius 類中定義運算符:
public static explicit operator Celsius(Fahrenheit fahr)
{
return new Celsius((5.0f / 9.0f) * (fahr.Degrees - 32));
}
如下所示,調(diào)用用戶定義的轉(zhuǎn)換運算符來強制轉(zhuǎn)換:
Fahrenheit fahr = new Fahrenheit(100.0f);
Console.Write($"{fahr.Degrees} Fahrenheit");
Celsius c = (Celsius)fahr;
此轉(zhuǎn)換運算符從源類型轉(zhuǎn)換為目標(biāo)類型。 源類型提供轉(zhuǎn)換運算符。 不同于隱式轉(zhuǎn)換,顯式轉(zhuǎn)換運算符必須通過轉(zhuǎn)換的方式來調(diào)用。 如果轉(zhuǎn)換操作會導(dǎo)致異?;騺G失信息,則應(yīng)將其標(biāo)記為 explicit。 這可阻止編譯器靜默調(diào)用可能產(chǎn)生意外后果的轉(zhuǎn)換操作。
省略轉(zhuǎn)換將導(dǎo)致編譯時錯誤 CS0266。
有關(guān)詳細(xì)信息,請參閱使用轉(zhuǎn)換運算符。
示例
下面的示例提供了 Fahrenheit 和 Celsius 類,其中每個類均提供轉(zhuǎn)換為其他類的顯式轉(zhuǎ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,它表示單個的十進制數(shù)字。 將運算符定義為從 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é)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
相關(guān)文章
C#實現(xiàn)Json轉(zhuǎn)Unicode的方法
這篇文章主要介紹了C#實現(xiàn)Json轉(zhuǎn)Unicode的方法,可實現(xiàn)輸入為帶有json格式的文本,輸出正常文本的功能,需要的朋友可以參考下2014-09-09
C#使用偽隨機數(shù)實現(xiàn)加密用戶密碼的方法
這篇文章主要介紹了C#使用偽隨機數(shù)實現(xiàn)加密用戶密碼的方法,對于開發(fā)C#會員系統(tǒng)或者程序安全問題都有一定的參考借鑒價值,需要的朋友可以參考下2014-07-07
C#中string和StingBuilder內(nèi)存中的區(qū)別實例分析
這篇文章主要介紹了C#中string和StingBuilder內(nèi)存中的區(qū)別,以實例形式演示了二者在內(nèi)存中的不同之處,需要的朋友可以參考下2014-09-09
C#?使用Aspose.Cells?導(dǎo)出Excel的步驟及問題記錄
Aspose.Cells是一款功能強大的Excel文檔處理和轉(zhuǎn)換控件,開發(fā)人員和客戶電腦無需安裝Microsoft Excel也能在應(yīng)用程序中實現(xiàn)類似Excel的強大數(shù)據(jù)管理功能,對C#?使用Aspose.Cells?導(dǎo)出Excel的步驟及問題記錄感興趣的朋友一起看看吧2022-01-01
C#開發(fā)微信門戶及應(yīng)用(1) 微信接口使用
這篇文章主要為大家詳細(xì)介紹了C#開發(fā)微信門戶及應(yīng)用第一篇,微信接口的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06

