เมื่อฉันมีคลาสที่มีตัวสร้างแบบคงที่คอนสตรัคเตอร์นั้นถูกเรียกเมื่อแอสเซมบลีที่มีคลาสถูกโหลดครั้งแรกหรือเมื่อการอ้างอิงแรกไปยังคลาสนั้นถูกตี
เมื่อฉันมีคลาสที่มีตัวสร้างแบบคงที่คอนสตรัคเตอร์นั้นถูกเรียกเมื่อแอสเซมบลีที่มีคลาสถูกโหลดครั้งแรกหรือเมื่อการอ้างอิงแรกไปยังคลาสนั้นถูกตี
คำตอบ:
เมื่อมีการเข้าถึงชั้นเรียนเป็นครั้งแรก
ตัวสร้างแบบคงที่ (คู่มือการเขียนโปรแกรม C #)
ตัวสร้างแบบคงที่ใช้เพื่อเตรียมข้อมูลเบื้องต้นให้กับข้อมูลคงที่หรือเพื่อดำเนินการเฉพาะที่ต้องดำเนินการเพียงครั้งเดียวเท่านั้น จะถูกเรียกโดยอัตโนมัติก่อนที่จะสร้างอินสแตนซ์แรกหรือมีการอ้างอิงสมาชิกแบบคงที่
A static constructor is used to initialize any static data
ไม่ ดีกว่าที่จะใช้static initializer
เพื่อเริ่มต้นสิ่งที่คงที่
มันไม่ง่ายอย่างที่คุณคาดหวังแม้จะมีเอกสารที่ตรงไปตรงมา บทความของ Jon Skeet http://csharpindepth.com/Articles/General/Beforefieldinit.aspxจะกล่าวถึงคำถามนี้โดยละเอียด
สรุป:
ตัวสร้างแบบคงที่รับประกันว่าจะดำเนินการทันทีก่อนการอ้างอิงครั้งแรกไปยังสมาชิกของคลาสนั้นไม่ว่าจะเป็นการสร้างอินสแตนซ์หรือวิธีการ / คุณสมบัติแบบคงที่ของตัวเอง
โปรดทราบว่าตัวเริ่มต้นแบบคงที่ (หากไม่มีตัวสร้างแบบคงที่) รับประกันว่าจะดำเนินการได้ทุกเมื่อก่อนที่จะอ้างอิงไปยังฟิลด์เฉพาะเป็นครั้งแรก
ตัวสร้างแบบคงที่ถูกเรียกใช้ก่อนที่คุณจะใช้อะไรก็ตามในคลาส แต่เมื่อสิ่งนั้นเกิดขึ้นจะขึ้นอยู่กับการนำไปใช้งาน
รับประกันว่าจะถูกเรียกก่อนที่จะเข้าถึงสมาชิกแบบคงที่ตัวแรกและก่อนที่จะสร้างอินสแตนซ์แรก หากไม่เคยใช้คลาสนี้จะไม่รับประกันว่าตัวสร้างแบบคงที่จะถูกเรียกเลย
ในกรณีที่วิธีการแบบคงที่ถูกเรียกใช้จากคลาสแม่ตัวสร้างแบบคงที่จะไม่ถูกเรียกแม้ว่าจะมีการระบุไว้อย่างชัดเจน นี่คือตัวอย่าง b constructor ไม่ได้ถูกเรียกว่า b.methoda () ถูกเรียก
static void Main(string[] args)
{
b.methoda();
}
class a
{
public static void methoda()
{
//using initialized method data
}
}
class b : a
{
static b()
{
//some initialization
}
}
ดูเหมือนว่าจะมี gotcha ที่มีตัวสร้างแบบคงที่ซึ่งมีคำตอบจากที่อื่น แต่ใช้เวลาสักครู่ในการสรุปเป็นคำอธิบายง่ายๆ เอกสารและคำอธิบายทั้งหมดอ้างว่าตัวสร้างแบบคงที่ / อินเทียร์ไลเซอร์นั้น "รับประกัน" ว่าจะทำงานก่อนที่คลาสแรกจะถูกสร้างอินสแตนซ์หรือมีการอ้างถึงฟิลด์สแตติกแรก gotcha เข้ามาเมื่อคุณพยายามใส่ซิงเกิลตันแบบคงที่ในคลาสที่สร้างอินสแตนซ์ของตัวมันเอง (ไก่ / ไข่) ในกรณีนี้ตัวสร้างแบบคงที่จะถูกเรียกหลังจากตัวสร้างอินสแตนซ์ - และในกรณีของฉันตัวสร้างอินสแตนซ์มีโค้ดที่อาศัยข้อมูลคงที่บางส่วน
ตัวสร้างแบบคงที่เรียกว่าหลังจากตัวสร้างอินสแตนซ์?
ตัวสร้างแบบคงที่สามารถทำงานหลังจากตัวสร้างแบบไม่คงที่ นี่คือบั๊กของคอมไพเลอร์หรือไม่?
(คำตอบสำหรับฉันคือใส่ซิงเกิลตันในคลาสแยกต่างหากหรือเริ่มต้นข้อมูลแบบคงที่ด้วยตนเองในตัวสร้างอินสแตนซ์ก่อนที่จะต้องใช้)