數值型別 (c # 參考)

數值型別參考型別是 c # 型別的兩個主要類別。 實值型別的變數包含型別的實例。 這與參考型別的變數不同,後者包含型別實例的參考。 根據預設,在 指派時,將引數傳遞至方法,並傳回方法結果,會複製變數值。 在實數值型別變數的情況下,會複製對應的型別實例。 下列範例示範了該行為:

using System;

public struct MutablePoint
{
    public int X;
    public int Y;

    public MutablePoint(int x, int y) => (X, Y) = (x, y);

    public override string ToString() => $"({X}, {Y})";
}

public class Program
{
    public static void Main()
    {
        var p1 = new MutablePoint(1, 2);
        var p2 = p1;
        p2.Y = 200;
        Console.WriteLine($"{nameof(p1)} after {nameof(p2)} is modified: {p1}");
        Console.WriteLine($"{nameof(p2)}: {p2}");

        MutateAndDisplay(p2);
        Console.WriteLine($"{nameof(p2)} after passing to a method: {p2}");
    }

    private static void MutateAndDisplay(MutablePoint p)
    {
        p.X = 100;
        Console.WriteLine($"Point mutated in a method: {p}");
    }
}
// Expected output:
// p1 after p2 is modified: (1, 2)
// p2: (1, 200)
// Point mutated in a method: (100, 200)
// p2 after passing to a method: (1, 200)

如先前的範例所示,實數值型別變數的作業只會影響儲存在變數中的實值型別實例。

如果實值型別包含參考型別的資料成員,則在複製值型別實例時,只會複製參考型別的實例參考。 複製和原始實數值型別實例都可以存取相同的參考型別實例。 下列範例示範了該行為:

using System;
using System.Collections.Generic;

public struct TaggedInteger
{
    public int Number;
    private List<string> tags;

    public TaggedInteger(int n)
    {
        Number = n;
        tags = new List<string>();
    }

    public void AddTag(string tag) => tags.Add(tag);

    public override string ToString() => $"{Number} [{string.Join(", ", tags)}]";
}

public class Program
{
    public static void Main()
    {
        var n1 = new TaggedInteger(0);
        n1.AddTag("A");
        Console.WriteLine(n1);  // output: 0 [A]

        var n2 = n1;
        n2.Number = 7;
        n2.AddTag("B");

        Console.WriteLine(n1);  // output: 0 [A, B]
        Console.WriteLine(n2);  // output: 7 [A, B]
    }
}

注意

若要讓您的程式碼較不容易出錯且更健全,請定義和使用不可變的實數值型別。 本文僅針對示範目的使用可變的實數值型別。

實數值型別和類型條件約束的種類

實值型別可以是下列兩種類型之一:

  • 封裝資料和相關功能的結構類型
  • 列舉型別,它是由一組命名常數所定義,代表一個選擇或一個選擇組合。

可為 null的實值型別 T? 代表其基礎實值型別的所有值 T ,以及一個額外的null值。 您無法指派 null 給實值型別的變數,除非它是可為 null 的實值型別。

您可以使用 struct 條件約束來指定型別參數為不可為 null 的實值型別。 結構和列舉類型都符合 struct 條件約束。 從 c # 7.3 開始,您可以 System.Enum 在稱為 列舉條件約束 的基類條件約束 (中使用,) 指定型別參數為列舉型別。

內建實數值型別

C # 提供下列內建實數值型別,也稱為 簡單類型

所有簡單類型都是結構類型,而且與其他結構類型不同,因為它們允許某些額外的作業:

  • 您可以使用常值提供簡單類型的值。 例如,'A'char 型別的常值,而 2001 則是 int 型別的常值。

  • 您可以使用 const 關鍵字來宣告簡單型別的常數。 不可能有其他結構類型的常數。

  • 常數運算式(其運算元都是簡單類型的常數)會在編譯時期評估。

從 c # 7.0 開始,c # 支援 值元組。 值元組是實數值型別,但不是簡單類型。

C# 語言規格

如需詳細資訊,請參閱 C# 語言規格的下列幾節:

另請參閱