C# 常量 結構體 委托

来源:https://www.cnblogs.com/BoiledYakult/archive/2023/05/02/17368258.html
-Advertisement-
Play Games

常量 const double PI = 3.1415926; 常量名命名一般使用大寫字母 枚舉類型 開發一個游戲,游戲角色有法師(Mage)、射手(Archer)、刺客(Assassin)、坦克(Tank)、鋪助(Support)、戰士(Warrior),等不同類型。 ❓如何存儲游戲角色 使用in ...


常量

const double PI = 3.1415926;

常量名命名一般使用大寫字母

枚舉類型

開發一個游戲,游戲角色有法師(Mage)、射手(Archer)、刺客(Assassin)、坦克(Tank)、鋪助(Support)、戰士(Warrior),等不同類型。

❓如何存儲游戲角色

  • 使用int類型 :創建一套規則,提前為各個類型角色綁定一個數字標識
  • 使用枚舉類型

什麼是枚舉類型?

枚舉類型是一種特殊的值類型,可以在枚舉類型中定義一組命名的數值常量。

如何聲明枚舉類型?

enum <enum_name>
{
	value1,
	value2,
	value3,
	...
	valuen
}

預設情況下,

  • 每個枚舉成員對應的數值都是int類型的
  • 按照枚舉成員的生命順序,自動按照0、1、2 ······ 進行常量賦值。

可以指定其他的整數類型代替預設類型,也可以顯示指定每一位枚舉成員的對應值:

public enum BorderSide : byte { Left = 1, Right, Top = 10, Bottom }

上面的開發場景利用枚舉類型就可以這樣來完成:

enum RoleType { Mage, Archer, Assassin, Tank, Support, Warrior }
static void Main(string[] args)
{
    RoleType Top = RoleType.Tank;
    Top = RoleType.Warrior;
}

image-20230502164650057

  • 枚舉類型的實例可以與它對應的整數值相互顯式轉換

  • RoleType Top = RoleType.Tank;
    int i=(int)Top;	// 3
    
  • 也可以顯式將一個枚舉類型轉換為另一個

  • 由於枚舉類型可以和它對應的整數類型相互轉換,因此枚舉的真實值可能超出枚舉類型成員的數值範圍,在使用過程中需要考慮類型安全問題

結構體

我們日常使用的變數,一般都是某一個單一的信息,比如一個學生的信息:

age
name
grade
studylD

❓對於一個學生信息的話,我們怎麼對這些信息進行一個整合呢?

  • 結構體

什麼是結構體?

  • 結構體是值類型數據結構。它使得一個單一變數可以存儲各種數據類型的相關數據。
  • struct 關鍵字用於創建結構體。

結構體的作用就是把某一類的變數進行整合,組成一個新的數據類型,相當於一個新的信息。

如何聲明結構體?

struct <struct_name>
{
	訪問許可權 type typename
	訪問許可權 ype typename
}

關於學生信息,就可以這樣來存儲:

struct Studentinfo
{
    public int age;
    public string name;
    public int grade;
    public int studylD;
}

static void Main(string[] args)
{
    Studentinfo xiaoming = new Studentinfo();
    xiaoming.age = 10;
    xiaoming.grade = 1;
    xiaoming.name = "小明";
    xiaoming.studylD = 107963212;
    Console.ReadKey();
}

結構體的構造語義如下:

  • 結構體隱式包含一個無法重寫的無參數構造器。此構造函數不允許刪除和重定義,並且這個無參數的構造函數會一直存在,並不會因為定義了其他帶參數的構造函數就消失,這一點和類不同。

    • 構造器的作用是初始化對象,構造器也就是構造函數,通俗的講就是你在實例化結構體也就是創建結構體對象時是new Studentinfo()還是new Studentinfo(10,1,"小明",107963212)
    • 構造函數(C# 編程指南)
  • 定義結構體的構造器時,必須顯式為每一個欄位賦值。

結構體構造函數(簡單概述)

結構類型都有一個預定義的,沒有參數的構造函數,這點與類是一樣的。

看這個場景:

struct A
{
    static A()
    {
        Console.WriteLine("I am A.");
    }
    public void Fun()
    {

    }
}
static void Main(string[] args)
{
    A a = new A();
    a.Fun(); //結構的實例成員被引用
    Console.ReadKey();
}

輸出結果為:I am A.

當你把a.Fun();註釋掉以後再次運行程式你會發現程式不會輸出任何東西。

❓那麼結構體的靜態構造函數何時觸發呢

答案是:結構體的實例成員被引用,結構體的靜態成員被引用,結構體顯式聲明的構造函數被調用。

就上上面說的:結構體隱式包含一個無法重寫的無參數構造器。此構造函數不允許刪除和重定義,並且這個無參數的構造函數會一直存在,並不會因為定義了其他帶參數的構造函數就消失,這一點和類不同。

我們拿類來做比較:

struct Name
{
    public string firstName;
    public string lastName;
    public string FullName()
    {
        return firstName + lastName;
    }
    //Name()
    //{
    //    Console.WriteLine("無參構造函數");
    //}
}
class _Name
{
    public string firstName;
    public string lastName;
    public string FullName()
    {
        return firstName + lastName;
    }
    public _Name()
    {
        Console.WriteLine("無參構造函數");
    }
}
static void Main(string[] args)
{
    Name name = new Name();
    name.firstName = "三";
    name.lastName = "張";
    Console.WriteLine(name.FullName());
    _Name name1 = new _Name();

    Console.ReadKey();
}

結構體Name中的Name()構造函數在取消註釋後編譯器會報錯,但是當你將Name()改成帶參的構造函數後編譯器就不會提示錯誤了。這個時候,按照類的思路來講,我們在創建結構體Name的對象時應該要完成結構體帶參構造的所有欄位的初始化,否則就會報錯。也就是說我們在創建Name結構體對象時應該這樣寫:

Name name = new Name("三","張");

但是我們發現,我們寫Name name = new Name();也是沒問題的,之所以為問題就是因為結構體隱式包含一個無法重寫的無參數構造器。

我們換到類裡面,將無參的構造函數改為帶參數的,此時_Name name1 = new _Name();就會報錯。

image-20230502185228652

此外,我們還可以發現,類的無參構造函數在初始化對象的時候就會調用,而結構體的靜態預設無參構造函數則不會,只有在上述三種情況中才會被調用。

image-20230502185720358

[C# 結構體](https://www.cnblogs.com/arxive/p/5799245.html)

實例構造函數(C# 編程指南)

C# 結構體(Struct)

結構體函數

struct Name
{
    public string firstName;
    public string lastName;
    public string FullName()
    {
        return firstName + lastName;
    }
}
static void Main(string[] args)
{
    Name name = new Name();
    name.firstName = "三";
    name.lastName = "張";
    Console.WriteLine(name.FullName());
    Console.ReadKey();
}

小練習

定義一個Vector3的結構體(這個結構體可以用來表示坐標,可以表示向量),在裡面定義一個Distance方法,用來取得一個向量的長度的。

冷知識:向量長度 可以百度 一個向量的長度等於他和他自己的內積的平方根

struct Vector3
{
    public double x; public double y; public double z;
    public double Distance()
    {
        return Math.Sqrt(z * z + x * x + y * y);
    }
}
static void Main(string[] args)
{
    Vector3 v1 = new Vector3();
    v1.x = 4;
    v1.y = 5;
    v1.z = 6;
    Console.WriteLine(v1.Distance());
    Console.ReadKey();
}

委托(簡單概述)

委托delegate是一種存儲函數引用的類型。

委托的定義指定了一個返回類型和一個參數列表。

定義了委托之後,就可以聲明該委托類型的變數,接著就可以把一個返回類型跟參數列表跟委托一樣的函數賦值給這個變數。

簡單來講,委托delegate是一種存儲數引用的類型。委托的定義指定了一個返回類型和一個參數列表定義了委托之後,就可以聲明該委托類型的變數,接著就可以把一個返回類型跟參數列表跟委托一樣的麗數賦值給這個變數。

static double Multiply(double param1, double param2)   
{
    return param1 * param2;
}
static double Divide(double param1, double param2)
{
    return param1 / param2;
}
delegate double MyDelegate(double param1, double param2);
static void Main(string[] args)
{
    MyDelegate delegate1;
    delegate1 = Multiply;
    Console.WriteLine(delegate1(2,4));  // 8
    delegate1 = Divide;
    Console.WriteLine(delegate1(4,2));   // 2
    Console.ReadKey();
}

可以理解為定義聲明一種特殊的函數,,只有個聲明,沒有具體的函數體內容,函數的類型是delegate,需要用同參數類型、數量以及同返回值的函數賦值給委托變數。

internal class Program
{
    delegate void OnDieDelegate();
    static void PLay(OnDieDelegate onDie)
    {
        Console.WriteLine("做任務");
        Console.WriteLine("玩家正在戰鬥");
        Console.WriteLine("死");
        if(onDie != null)
        {
            onDie();
        }
    }
    static void ShowDieUI()
    {
        Console.WriteLine("顯示游戲死亡後的UI");
        Console.WriteLine("返迴首頁UI");
    }

    static void Main(string[] args)
    {
        PLay(ShowDieUI);
        PLay(null);
        Console.ReadKey();
    }
}

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

-Advertisement-
Play Games
更多相關文章
  • Java讀取資料庫表 package com.easycrud.builder; import com.easycrud.utils.PropertiesUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ja ...
  • 在上個世紀的文章中,老周簡單介紹了 QWindow 類的基本使用——包括從 QWindow 類派生和從 QRasterWindow 類派生。 其實,QWindow 類並不是只能充當主視窗用,它也可以嵌套到父級視窗中,變成子級對象。咱們一般稱之為【控制項】。F 話不多講,下麵咱們用實際案例來說明。 這個 ...
  • 讀取properties配置文件 package com.easycrud.utils; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.Map; ...
  • 消除idea頂部視窗上的白色標題欄 點擊Hlep,找到Edit Custom VM Options...點擊 添加下麵一段話(如果有責顯示為false責改為true): -Dide.win.frame.decoration=true 然後重啟即可,如下圖所示,頂部白框已經沒有出現了 ...
  • 有時,需要將 int 這樣的基本類型轉換為對象。所有的基本類型都有一個與之對應的類。例如,Integer 類對應基本類型 int。通常,這些類被稱為包裝器(wrapper)。這些對象包裝器類擁有很明顯的名字:Integer、Long、Float、Double、Short、Byte、Character ...
  • 構造 ServerSocket ServerSocket 的構造方法有以下幾種重載形式 ServerSocket() throws IOException ServerSocket(int port) throws IOException ServerSocket(int port, int bac ...
  • 在實際開發過程中,有時候會遇到如何編寫Go開機自啟服務的需求,在linux中我們可以使用systemd來進行托管,windows下可以通過註冊表來實現,mac下可以通過launchd來實現,上面的方式對於開發者來說,並不是什麼困難的事情,但是對於使用者而言,是並不希望通過這麼複雜的方式來達到開機自啟 ...
  • Pandas是一個開源的Python數據分析庫。 它提供了快速,靈活和富有表現力的數據結構,旨在使數據清洗和分析變得簡單而快速。 Pandas是基於NumPy數組構建的,因此它在許多NumPy函數上提供了直接的支持。它還提供了用於對錶格數據進行操作的數據結構,例如Series和DataFrame。 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...