共用方式為


readonly (C# 參考)

readonly關鍵詞是可在五個內容中使用的修飾詞:

  • 欄位宣告中, readonly 表示欄位的工作分派只能當做宣告的一部分或在同一類別的建構函式中發生。 在欄位宣告和建構函式內,唯讀欄位可以多次被指派和重新指派。

    建構函式結束後,readonly欄位不能被指派。 此規則對實值類型和參考型別有不同的影響:

    • 因為實值型別會直接包含其數據,所以實值型別的 readonly 欄位是不可變的。
    • 由於參考型別包含其數據的參考,因此,參考型別的 readonly 欄位一律必須參考相同的物件。 該物件可能不可變。 readonly修飾詞可防止以參考型別的不同實例取代域值。 不過,修飾詞不會防止欄位的實例數據被透過只讀欄位進行修改。

    警告

    外部可見的類型,若包含外部可見的只讀欄位,而該欄位是不可變的參考型別,可能構成安全性漏洞,並可能會觸發警告 CA2104:「請勿宣告可變的只讀參考型別」。

  • readonly struct在類型定義中,readonly表示結構類型是不可變的。 如需詳細資訊,請參閱readonly結構類型一文的結構一節。

  • 在結構類型內的實例成員宣告中, readonly 表示實例成員不會修改結構的狀態。 如需詳細資訊,請參閱readonly結構類型一文的實例成員一節。

  • ref readonly方法傳回中,readonly修飾詞表示方法會傳回參考且不允許寫入到該參考。

Readonly 欄位範例

在此範例中,即使已在類別建構函式中指派值,也無法在 方法year中變更域ChangeYear的值:

class Age
{
    private readonly int _year;
    Age(int year)
    {
        _year = year;
    }
    void ChangeYear()
    {
        //_year = 1967; // Compile error if uncommented.
    }
}

您只能在下列內容中將值指派給 readonly 欄位:

  • 在宣告中初始化變數時,例如:

    public readonly int y = 5;
    
  • 在包含實例欄位宣告之 類別的實例建構函式中。

  • 在包含靜態欄位宣告之類別的靜態建構函式中。

這些建構函式上下文是唯一可以將 readonly 欄位作為 outref 參數傳遞的有效上下文。

備註

關鍵詞 readonlyconst 關鍵詞不同。 const 欄位只能在欄位宣告時初始化。 readonly欄位可以在欄位宣告和任何建構函式中多次指派欄位。 因此,視所使用的建構函式而定,readonly 欄位可以有不同的值。 此外,雖然 const 欄位是編譯時間常數,readonly 欄位可用於執行時期常數,如下列範例所示:

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;
public class SamplePoint
{
    public int x;
    // Initialize a readonly field
    public readonly int y = 25;
    public readonly int z;

    public SamplePoint()
    {
        // Initialize a readonly instance field
        z = 24;
    }

    public SamplePoint(int p1, int p2, int p3)
    {
        x = p1;
        y = p2;
        z = p3;
    }

    public static void Main()
    {
        SamplePoint p1 = new SamplePoint(11, 21, 32);   // OK
        Console.WriteLine($"p1: x={p1.x}, y={p1.y}, z={p1.z}");
        SamplePoint p2 = new SamplePoint();
        p2.x = 55;   // OK
        Console.WriteLine($"p2: x={p2.x}, y={p2.y}, z={p2.z}");
    }
    /*
     Output:
        p1: x=11, y=21, z=32
        p2: x=55, y=25, z=24
    */
}

在上述範例中,如果您使用類似下列範例的 語句:

p2.y = 66;        // Error

您會收到編譯程式錯誤訊息:

唯讀欄位無法指定給 (在建構函式或變數初始化運算式中除外)

唯讀執行個體成員

您也可以使用 readonly 修飾詞,宣告執行個體成員不會修改結構的狀態。

public readonly double Sum()
{
    return X + Y;
}

備註

在讀取/寫入屬性的情況下,您可以將readonly修飾詞新增至get存取子。 某些 get 存取子可能會執行計算並快取結果,而不只是傳回私用字段的值。 將 readonly 修飾詞新增至 get 存取子,可確保 get 存取子不會藉由快取任何結果來修改對象的內部狀態。

您可以在readonly一文的實例成員一節中找到更多範例。

Ref readonly 傳回範例

readonly 修飾詞在 ref return 上表示傳回的參考無法修改。 下列範例會傳回來源的參考。 它會使用 readonly 修飾詞來指出呼叫端無法修改原點:

private static readonly SamplePoint s_origin = new SamplePoint(0, 0, 0);
public static ref readonly SamplePoint Origin => ref s_origin;

傳回的類型不需要是 readonly struct。 可以由 ref 傳回的任何型別都可以由 ref readonly 傳回。

Readonly ref readonly 回傳範例

ref readonly return也可以與型別上的readonly實例成員搭配struct使用:

public struct ReadonlyRefReadonlyExample
{
    private int _data;

    public readonly ref readonly int ReadonlyRefReadonly(ref int reference)
    {
        // _data = 1; // Compile error if uncommented.
        return ref reference;
    }
}

方法基本上會與實例成員一起傳回 readonly 參考(在此案例中為方法) readonly (無法修改任何實例欄位)。

C# 語言規格

如需詳細資訊,請參閱<C# 語言規格>。 語言規格是 C# 語法和使用方式的最終來源。

您也可以檢視語言規格提案:

另請參閱