readonly
您只能在下列內容中將值指派給readonly 欄位︰
1.在宣告中初始化變數時
2.在包含執行個體欄位宣告的類別執行個體建構函式
3.在包含靜態欄位宣告的類別靜態建構函式。
限制:
1.由於實值型別會直接包含其資料,因此具有readonly 實值型別的欄位是不可變的。
2.由於參考型別包含針對其資料的參考,因此readonly 參考型別的欄位必須一律參考相同的物件。 那個物件不是不變的。readonly 修飾詞可防止欄位被不同的參考型別執行個體取代。 但是,修改器不會阻止通過唯讀欄位修改欄位的實例數據。
3.在類型readonly struct定義中readonly, 指示結構類型不可變
4.在結構類型的實體成員聲明中,readonly指示實體成員不修改結構的狀態
5.在ref readonly方法返回中readonly, 修飾符指示該方法返回引用,並且不允許寫入該引用。
6.可以和struct或ref一起使用
readonly結構的所有資料成員必須唯讀如下:1.任何欄位聲明必須具有readonly變更器
2.任何屬性(包括自動實作的屬性)都必須是唯讀的(索引子不需要本身就是)
7.不能將readonly修改器應用於結構類型的靜態成員。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Exercisc : MonoBehaviour
{
public class Number
{
public readonly int a;
public int b;
public readonly int c = 200;
public readonly int d;
public Number()
{
d = 100;
}
public Number(int x, int y, int z, int r)
{
a = x;
b = y;
c = z;
d = r;
}
public void Modify(int x, int y, int z, int r)//不能使用方法函數來修改readonly值
{
a = x;
b = y;
c = z;
d = r;
}
}
void Start()
{
Number num_a = new Number();
Debug.Log($"1a:{ num_a.a} b:{num_a.b} c:{num_a.c} d:{num_a.d}");
Number num_b = new Number(20, 30, 40, 50);
Debug.Log($"2a:{ num_b.a} b:{num_b.b} c:{num_b.c} d:{num_b.d}");
Number num_c = new Number(10, 20, 30, 40);
//num_c.a = 100;//會出現錯誤有readonly不能只接修改
Debug.Log($"3a:{ num_c.a} b:{num_c.b} c:{num_c.c} d:{num_c.d}");
num_c = new Number();
Debug.Log($"4a:{ num_c.a} b:{num_c.b} c:{num_c.c} d:{num_c.d}");
num_c.b = 200;
Debug.Log($"5a:{ num_c.a} b:{num_c.b} c:{num_c.c} d:{num_c.d}");
//
1a:0 b:0 c:200 d:100
2a:20 b:30 c:40 d:50
3a:10 b:20 c:30 d:40
4a:0 b:0 c:200 d:100
5a:0 b:200 c:200 d:100
}
}
Struct
限制:
1.結構可帶有方法、字段、索引、屬性、運算符方法和事件。
2.結構可定義構造函數,但不能定義析構函數。但是,您不能為結構定義無參構造函數。無參構造函數(默認)是自動定義的,且不能被改變。
3.與類不同,結構不能繼承其他的結構或類。
4.結構不能作為其他結構或類的基礎結構。
5.結構可實現一個或多個接口。
6.結構成員不能指定為 abstract、virtual 或 protected。
7.當您使用 New 操作符創建一個結構對象時,會調用適當的構造函數來創建結構。與類不同,結構可以不使用 New 操作符即可被實例化。
8.如果不使用 New 操作符,只有在所有的字段都被初始化之後,字段才被賦值,對象才被使用。
9.結構類型可以實現介面
類和結構有以下幾個基本的不同點:
1.類是引用類型,結構是值類型。
2.結構不支持繼承。
3.結構不能聲明默認的構造函數。
4.結構中不能賦予初始值但類可以
struct Str1
{
public int a=20;//不行
}
public class Cla1
{
public int a = 20;//可以
}
5.甚麼時候使用class或是struct
1.描述一個輕量級對象的時候,結構可提高效率,類速度比較快。假如我們在傳值的時候希望傳遞的是對象的引用地址而不是對象的拷貝,就應該使用類了。
2.struct比較適合程式碼不複雜的,而class適合很多程式碼的邏輯運算
3.需要繼承的就要使用class
//只有struct
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Exercisc : MonoBehaviour
{
public struct Number
{
public int a;
public int b;
public int c ;
public int d;
public int Q { get; }
//public const int j = 100;
public static int k = 100;//只有const和靜態可以初始化
public Number(int x, int y, int z, int r)
{
a = x;
b = y;
c = z;
d = r;
Q = 100;
}
public void Display()
{
Debug.Log($"a:{a} b:{b} c:{c} d:{d} Q:{Q}");
}
}
void Start()
{
Number num_a=new Number();//要先初始化才能附值
num_a.Display();
num_a.a = 200;
num_a.Display();
//
a:0 b:0 c:0 d:0 Q:0
a:200 b:0 c:0 d:0 Q:0
}
}
//使用readonly struct
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Exercisc : MonoBehaviour
{
public readonly struct Number
{
public readonly int a;
public readonly int b;
public readonly int c ;
public readonly int d;
public int Q { get; }
public Number(int x, int y, int z, int r)
{
a = x;
b = y;
c = z;
d = r;
Q = 100;//struct 的屬性和索引子一定要附值
}
public void Display()
{
Debug.Log($"a:{a} b:{b} c:{c} d:{d} Q:{Q}");
}
}
void Start()
{
Number num_a=new Number(1,2,3,4);
num_a.Display();
//a:1 b:2 c:3 d:4 Q:100
}
}