[C#/Unity] 為甚麼要用readonly和const

        我在看其他人的代碼時,很多時候都會看見在他們的字段上,經常會寫readonly和const這樣的修飾符。有時候自己會覺得,為什麼要加這些看似是多餘的東西?明明只要直接聲明一般的字段也可以,比如:public int x, private Vector3 pos等等,這些字段可讀可寫,使用起來非常方便,為甚麼我們還要故意為難自己,寫一個就算在類裡面,也只能取值,不能更改值的字段呢?

        但是隨著自己寫代碼的經驗的一點一點地積累上去,就開始能發現一些字段在不使用const和readonly進行修飾反而會使情況變得更麻煩。

        在我們遊戲開發的過程中,其實有很多的變量/字段都可能是需要頻繁使用,但是這些變量/字段的值又是在那個物體/類在實例化的時候、甚至是遊戲一開始時就已經決定好而且之後都不會再進行改變的,那麼我們在這些字段之前加上readonly或const的話,在使用的時候不但會更方便,也會更加安全。說的更準確一點的話,readonly會讓字段使用更安全,const會讓字段使用更方便。       

const(常量)

        被const修飾的變量必須在被聲明的時候完成初始化,而且會從遊戲一開始就存在直到程序終止。而且由於const的變量是靜態的,可以直接通過類來獲得,因此,就我自己而言,我都會將一些常用的、重要的字符串比如Tag的名字、音效名字等等,事先寫在一個靜態的UsualString類裡,然後當我需要使用這些字符串的時候,就可以通過直接通過這個UsualString類直接訪問變量,避免自己手動輸入字符串時出錯。

public static class UsualString

{

        public const string tagName = “TagName”;

        public const string sfxName = “BlinkSFX”;        

}

readonly(唯讀)

        被readonly修飾的字段只能在兩種情況下完成賦值,而且在賦值完成之後,之後我們就再也不能對字段的值作出改動,使之變成了一個「唯讀」的字段。這裡我以一個Enemy類為例,在Enemy裡面,有一個readonly Vector3 spawnPos的字段,這個字段是Enemy的生成位置。

    • 可以在類的構造方法進行賦值,也就是當前類被實例化時賦值

public class Enemy

{

        public readonly Vector3 spawnPos;

        public Enemy(Vector3 pos)

        {

                spawnPos = pos;

        }

}

    • 也可以在聲明這個變量的時候就完成賦值

public class Enemy

{

        public readonly Vector3 spawnPos = Vector3.zero;

}

        要注意的是readonly 是非靜態的,如果我們要在其他類中拿到readonly的字段,也必須通過實例對象來訪問。當然,我們也可以把這個readonly的字段手動聲明為static,使之可以直接通過類取得

        static readonly的使用與const的效果相似,不過static readonly的初始化比const靈活,既可以在聲明時初始化,也可以在類的靜態無參構造函數裡進行初始化,但相對的,效能也較直接使用const要差一點。總體而言,static readonly的使用相對比較複雜,也比較少用,盡量還是使用readonly和const會更好。