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
條件約束。 您可以在稱為列舉條件約束的基類條件約束 (中使用 System.Enum
,) 指定類型參數是列舉型別。
內建實數值型別
C# 提供下列內建實數值型別,也稱為 簡單類型:
所有簡單類型都是結構類型,與其他結構類型不同,因為它們允許某些額外的作業:
您可以使用常值來提供簡單類型的值。 例如,
'A'
是char
型別的常值,而2001
則是int
型別的常值。您可以使用 const 關鍵字來宣告簡單型別的常數。 不可能有其他結構類型的常數。
常數運算式,其運算元都是簡單型別的常數,會在編譯時期進行評估。
值元組是實值型別,但不是簡單型別。
C# 語言規格
如需詳細資訊,請參閱 C# 語言規格的下列幾節: