C#-12 轉換

来源:https://www.cnblogs.com/wwwen/archive/2022/05/07/16230412.html
-Advertisement-
Play Games

一 什麼是轉換 轉換是接受一個類型的值並使用它作為另一個類型的等價值的過程。 下列代碼演示了將1個short類型的值強制轉換成byte類型的值。 short var1 = 5; byte var2 = 10; var2 = (byte) var1; //強制轉換,將var1的值轉換成byte類型 二 ...


一 什麼是轉換

轉換是接受一個類型的值並使用它作為另一個類型的等價值的過程。

下列代碼演示了將1個short類型的值強制轉換成byte類型的值。

short var1 = 5;
byte var2 = 10;

var2 = (byte) var1;    //強制轉換,將var1的值轉換成byte類型

 

二 隱式轉換

有些類型的轉換不會丟失數據與精度,如將8位的值轉換成16位的值是非常容易的,不會丟失精度。

C#語言會自動進行轉換,稱為隱式轉換。

從位數更少的源轉換成位數更多的目標類型時,目標中多出的位需要用0或1填充。

當從更小的無符號類型轉換為更大的無符號類型時,目標類型多出的最高位都以0進行填充,這叫做零擴展。

下圖演示使用零擴展將8位的10轉換成16位的10:

 

對於有符號類型的轉換而言,額外的高位用源表達式的符號位進行填充,這樣就維持了被轉換值的正確符號和大小。 

下圖演示符號擴展:

 

三 顯示轉換和強制轉換

嘗試將ushort值1365轉換為byte值,會導致數據丟失。

 

對於預定義類型,C#會自動將一個數據類型轉換成另一個數據類型,但只是針對那些從源類型到目標類型不會發生數據丟失的情況。

而對於從源類型到目標類型轉換會發生數據丟失的情況,C#不提供自動轉換,就需要使用顯示轉換。這叫做強制轉換表達式。

四 轉換的類型

有很多標準的、預定義的用於數字和引用的轉換。

 

 

除了標準轉換,還可以為自定義類型定義隱式轉換和顯示轉換。

裝箱:將值類型轉換為object類型、System.ValueType類型。

拆箱:將一個裝箱的值轉換為原始類型。

五 引用轉換

引用類型對象有記憶體中的兩部分組成:引用和數據。

由引用保存的那部分信息是它指向的數據類型。

引用轉換接受源引用並返回一個指向堆中同一位置的引用,但是把引用標記為轉換的目標類型。

下例給出兩個引用變數,myVar1和myVar2,它們指向記憶體中的相同對象。

class Program
{
    static void Main(string[] args)
    {
        B myVar1 = new B();
        A myVar2 = (A)myVar1;   //將myVar1作為A類的引用返回

        Console.WriteLine(myVar1.Field1);   //正確
        Console.WriteLine(myVar2.Field2);   //錯誤,Field2對於myVar2不可見
    }
}

class A { public int Field1; }

class B : A { public int Field2; }

5.1 隱式引用轉換

C#可以自動實現隱式引用轉換。

  • 所有引用類型都可以被隱式轉換為object類型;
  • 任何類型可以隱式轉換到它繼承的介面;
  • 類可以隱式轉換到它繼承鏈中的任何類和它實現的任何介面。

5.2 顯示引用轉換

顯示引用轉換是從一個普通類型到一個更精確類型的引用轉換。

顯示轉換包括:

  • 從object到任何引用類型的轉換;
  • 從基類到從它繼承的類的轉換。

六 裝箱轉換和拆箱轉換

6.1 裝箱轉換

裝箱是一種隱式轉換,它接受值類型的值,根據這個值在堆中創建一個完整的引用類型對象並返回對象引用。

6.2 拆箱轉換

拆箱是把裝箱後的對象轉換回值類型對象的過程。

拆箱是顯示轉換。

系統在把值拆箱成ValueTypeT時執行瞭如下步驟:

  • 它檢測到要拆箱的對象實際是ValueTypeT的裝箱值;
  • 它把對象的值複製到變數。

七 用戶自定義轉換

除了標準轉換,我們還可以為類和結構自定義隱式轉換和顯示轉換。

 語法如下:

public static implicit operator TargetType (SourceType Identifier)
{
       . . .
       return ObjectOfTargetType   
}      

用戶自定義轉換的約束:

  • 只可以為類和結構定義用戶自定義轉換;
  • 不能重定義標準隱式轉換或顯示轉換;
  • 對於源類型S和目標類型T,S和T必須是不同類型;
  • S和T不能通過繼承關聯,S和T都不能是介面類型或object類型;
  • 轉換運算符必須是S或T的成員。 

implicit:隱式轉換
explicit:顯示轉換,需要強制轉換表達式

下麵演示一個用戶自定義轉換的例子:

class Program
{
    static void Main(string[] args)
    {
        Person bill = new Person("bill", 25);
        int age = bill;     //將Person對象轉換為int
        Console.WriteLine($"Person Info :{bill.Name},{age}");

        Person none = 35;   //將int轉換為Person對象
        Console.WriteLine($"Person Info :{none.Name},{none.Age}");

        //輸出:
        //Person Info :bill,25
        //Person Info :none,35
    }
}

class Person
{
    public string Name;
    public int Age;

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    //將Person隱式轉換為int
    public static implicit operator int(Person p)
    {
        return p.Age;
    }

    //將int隱式轉換為Person
    public static implicit operator Person(int i)
    {
        return new Person("none", i);
    }
}

八 is運算符和as運算符

有些轉換是非法的,會在運行時拋出一個InvalidCastException異常。我們可以使用Is運算符來檢查轉換是否會成功完成。

as運算符和強制轉換運算符類似,只是它不拋出異常。如果轉換失敗,它返回null而不是拋出異常。

class Program
{
    static void Main(string[] args)
    {
        var student = new Student();
        student.Name = "jack";
        student.Age = 16;
        // is 第1種用法:檢測student是否能轉換為Person類型,如果可以,則返回true
        if (student is Person)
        {
            Console.WriteLine("stundent is Person");
        }
        // is 第2種用法:檢測student是否能轉換為Person類型,如果可以,則返回true,並將其轉換賦值給Person類型的變數p
        if (student is Person p)
        {
            Console.WriteLine($"Person p:{p.Name},{p.Age}");
        }

        // as 用法
        var p1 = student as Person;
        if (p1 != null)
        {
            Console.WriteLine($"Person p:{p1.Name},{p1.Age}");
        }
    }
}

class Person
{
    public string Name;
    public int Age;
}

class Student : Person { }

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Python代碼規範 代碼規範這東西也是很重要的,一定要註意 給你舉個例子: 你代碼全部寫對了,但是你的代碼規範沒弄好,找個半天,不知道錯哪了,那感覺,簡直不要太崩潰 好啦,下麵我們開始學習吧~ 一、簡明概述 1、編碼 如無特殊情況, 文件一律使用 UTF-8 編碼如無特殊情況, 文件頭部必須加入 ...
  • 一個工作了4年的小伙伴,他說他從線下培訓就開始接觸Spring,到現在已經快5年時間了。 從來沒有想過,為什麼要使用Spring 框架。 結果在面試的時候,竟然遇到一個這樣的問題。 大腦一時間短路了,來求助我,這類問題應該怎麼去回答。 下麵我們來看看普通人和高手的回答 普通人: 嗯。。。。。。。。。 ...
  • 二分查找實際上就是採用了分治法的思想 以下模板都以升序數組為準 模板一: 標準的二分查找 場景:數組元素有序且不重覆 有的話返回索引,沒有返回-1 int binarySearch(vector<int>& arr, int target) { int left = 0, right = nums. ...
  • 原創:微信公眾號 【阿Q說代碼】,歡迎分享,轉載請保留出處。 之前寫過一篇名為《看了同事寫的代碼,我竟然開始默默的模仿了。。。》的文章,今天偶然間看了下後臺數據,大吃一驚。該文章的閱讀量在微信公眾號內竟然達到了驚人的5W+ 。對於沒見過市面的我來說已經相當滿足了。 當然,能達到這樣的數據離不開各位大 ...
  • 近幾年網路發展的越來越好,其中的功勞離不開默默付出的程式員,正是他們任勞任怨的付出,才換來現在的便捷,在程式員匯聚的論壇,一名程式員卻道出另一種現象:好久沒打代碼了,回想以前辭職到老家礦洞里秘密開發的日子,二年整整敲了45萬行代碼。 這便是該程式員的原文,在貼文最下方,還曬出山洞的全景樣貌,山洞看起 ...
  • 回顧總結 到目前為止,Spring源碼中AbstractApplicationContext#refresh方法的已經解讀到第11個方法finishBeanFactoryInitialization,前10個方法介紹了: BeanFactory的準備,創建,刷新,個性化BeanFactory的擴展點 ...
  • package com.oop.demo06;public class Person { public void run(){ System.out.println("run"); }} package com.oop.demo06;public class Student extends Pers ...
  • 1、前言 好久沒有更新博客了,最近沒什麼假期,但是卻比以前還忙!工作、工作、工作,就像趕集似的,聚在一起。這個上海啥時候才能解封困在這裡暗無天日的。早點解封出去看看想見的人的人,做做該做的事。工作中有那麼一個需求客戶想要通過自己選擇列表的checkbox然後下載所選列表裡面的圖片,圖片我們是存在圖片 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...