const
และreadonly
มีความคล้ายคลึงกัน แต่ไม่เหมือนกันทั้งหมด
const
ฟิลด์เป็นค่าคงที่รวบรวมเวลาหมายความว่าค่าที่สามารถคำนวณที่รวบรวมเวลา readonly
ฟิลด์ช่วยให้สถานการณ์เพิ่มเติมในรหัสบางอย่างจะต้องทำงานในระหว่างการก่อสร้างประเภท หลังจากการก่อสร้างreadonly
จะไม่สามารถเปลี่ยนฟิลด์ได้
ตัวอย่างเช่นconst
สมาชิกสามารถใช้เพื่อกำหนดสมาชิกเช่น:
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
เนื่องจากค่าเช่น 3.14 และ 0 เป็นค่าคงที่เวลาคอมไพล์ อย่างไรก็ตามพิจารณากรณีที่คุณกำหนดประเภทและต้องการให้อินสแตนซ์ pre-fab บางอย่างของมัน ตัวอย่างเช่นคุณอาจต้องการกำหนดคลาสสีและให้ "ค่าคงที่" สำหรับสีทั่วไปเช่นสีดำสีขาว ฯลฯ คุณไม่สามารถทำสิ่งนี้กับสมาชิก const เนื่องจากด้านขวามือไม่ใช่ค่าคงที่เวลาคอมไพล์ หนึ่งสามารถทำได้กับสมาชิกคงที่ปกติ:
public class Color
{
public static Color Black = new Color(0, 0, 0);
public static Color White = new Color(255, 255, 255);
public static Color Red = new Color(255, 0, 0);
public static Color Green = new Color(0, 255, 0);
public static Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
แต่ก็ไม่มีอะไรที่จะป้องกันลูกค้าของ Color จากการลอกคราบมันอาจจะโดยการสลับค่าขาวดำ ไม่จำเป็นต้องพูดสิ่งนี้จะทำให้เกิดความหวาดกลัวสำหรับลูกค้ารายอื่น ๆ ของคลาสสี คุณลักษณะ "อ่านอย่างเดียว" กล่าวถึงสถานการณ์นี้
เพียงแค่แนะนำreadonly
คำสำคัญในการประกาศเราจะรักษาความยืดหยุ่นในการเริ่มต้นในขณะที่ป้องกันไม่ให้ลูกค้ารหัสจากการล้อเล่น
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
เป็นที่น่าสนใจที่จะทราบว่าสมาชิก const มักจะคงที่ในขณะที่สมาชิกแบบอ่านอย่างเดียวอาจเป็นแบบคงที่หรือไม่เช่นเดียวกับเขตข้อมูลปกติ
เป็นไปได้ที่จะใช้คำหลักเดียวสำหรับสองวัตถุประสงค์นี้นำไปสู่ปัญหาการกำหนดเวอร์ชันหรือปัญหาประสิทธิภาพ สมมติว่าเราใช้คำหลักคำเดียว (const) และผู้พัฒนาเขียน:
public class A
{
public static const C = 0;
}
และนักพัฒนาซอฟต์แวร์คนอื่นเขียนโค้ดที่ใช้ A:
public class B
{
static void Main() => Console.WriteLine(A.C);
}
ตอนนี้โค้ดที่สร้างขึ้นสามารถขึ้นอยู่กับความจริงที่ว่า AC เป็นค่าคงที่เวลารวบรวมได้หรือไม่? คือสามารถใช้ AC แทนค่า 0 ได้หรือไม่? หากคุณพูดว่า "ใช่" นี่หมายความว่าผู้พัฒนา A ไม่สามารถเปลี่ยนวิธีการเริ่มต้น AC ได้ - สิ่งนี้จะอยู่ในมือของผู้พัฒนา A โดยไม่ได้รับอนุญาต
หากคุณพูดว่า "ไม่" สำหรับคำถามนี้การเพิ่มประสิทธิภาพที่สำคัญจะพลาดไป บางทีผู้เขียน A อาจเป็นบวกว่า AC จะเป็นศูนย์เสมอ การใช้ทั้ง const และอ่านอย่างเดียวทำให้นักพัฒนา A สามารถระบุเจตนาได้ สิ่งนี้ทำให้เกิดพฤติกรรมการกำหนดเวอร์ชันที่ดีขึ้นและประสิทธิภาพที่ดีขึ้น
static readonly
: ลองใช้ const ภายในIEnumerator
ซึ่งจะก่อให้เกิดunrecheableyield
และคุณจะได้รับหวั่น "รวบรวมข้อผิดพลาดภายใน" ผมไม่ได้ทดสอบรหัสนอก Unity3D แต่ผมเชื่อว่านี้เป็นทั้งขาวดำหรือ.NET ข้อผิดพลาด มันเป็นปัญหาc #อย่างไรก็ตาม