常量 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;
}
-
枚舉類型的實例可以與它對應的整數值相互顯式轉換
-
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();
就會報錯。
此外,我們還可以發現,類的無參構造函數在初始化對象的時候就會調用,而結構體的靜態預設無參構造函數則不會,只有在上述三種情況中才會被調用。
結構體函數
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();
}
}