Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

การใช้คอนสตรัคเตอร์แบบคงที่ใน C # คืออะไร?


ตัวสร้างแบบคงที่ใช้เพื่อเริ่มต้นข้อมูลแบบคงที่หรือเพื่อดำเนินการเฉพาะที่ต้องทำเพียงครั้งเดียวเท่านั้น มันถูกเรียกโดยอัตโนมัติก่อนที่จะสร้างอินสแตนซ์แรกหรืออ้างอิงสมาชิกแบบคงที่

ตัวสร้างแบบคงที่มีประโยชน์เมื่อสร้างคลาส wrapper สำหรับโค้ดที่ไม่มีการจัดการ เมื่อตัวสร้างสามารถเรียกใช้เมธอด LoadLibrary ตัวสร้างแบบคงที่ยังเป็นสถานที่ที่สะดวกในการบังคับใช้การตรวจสอบรันไทม์กับพารามิเตอร์ประเภทที่ไม่สามารถตรวจสอบได้ในเวลารวบรวมผ่านข้อจำกัด

ตัวสร้างแบบคงที่มีคุณสมบัติดังต่อไปนี้ -

  • ตัวสร้างแบบคงที่ไม่รับตัวแก้ไขการเข้าถึงหรือมีพารามิเตอร์

  • คลาสหรือโครงสร้างสามารถมีคอนสตรัคเตอร์แบบคงที่ได้เพียงตัวเดียวเท่านั้น

  • ตัวสร้างแบบคงที่ไม่สามารถสืบทอดหรือโอเวอร์โหลดได้

  • คอนสตรัคเตอร์แบบสแตติกไม่สามารถเรียกได้โดยตรงและมีไว้เพื่อเรียกโดยรันไทม์ภาษาทั่วไป (CLR) เท่านั้น มันถูกเรียกใช้โดยอัตโนมัติ

  • ผู้ใช้ไม่มีการควบคุมเมื่อคอนสตรัคเตอร์แบบสแตติกถูกเรียกใช้งานในโปรแกรม

  • ตัวสร้างแบบคงที่ถูกเรียกโดยอัตโนมัติเพื่อเริ่มต้นคลาสก่อนที่จะสร้างอินสแตนซ์แรกหรืออ้างอิงสมาชิกแบบคงที่ staticconstructor จะทำงานก่อนตัวสร้างอินสแตนซ์ คอนสตรัคทอริสแบบคงที่ของประเภทถูกเรียกเมื่อเมธอดสแตติกที่กำหนดให้กับเหตุการณ์หรือผู้รับมอบสิทธิ์ถูกเรียกใช้และไม่ได้ถูกเรียกเมื่อถูกกำหนด หากมีตัวกำหนดค่าเริ่มต้นของตัวแปรฟิลด์สแตติกอยู่ในคลาสของคอนสตรัคเตอร์แบบคงที่ พวกเขาจะถูกดำเนินการในลำดับข้อความซึ่งจะปรากฏในการประกาศคลาสทันทีก่อนที่จะดำเนินการของคอนสตรัคคอนสตรัค

  • หากคุณไม่ได้จัดเตรียมคอนสตรัคเตอร์แบบคงที่เพื่อเริ่มต้นฟิลด์สแตติก ฟิลด์สแตติกทั้งหมดจะถูกเริ่มต้นเป็นค่าเริ่มต้นตามที่ระบุไว้ในค่าเริ่มต้นของประเภท C#

  • หากคอนสตรัคเตอร์แบบคงที่ส่งข้อยกเว้น รันไทม์จะไม่เรียกใช้เป็นครั้งที่สอง และประเภทจะยังไม่ได้กำหนดค่าเริ่มต้นตลอดอายุของโดเมนแอปพลิเคชันที่โปรแกรมของคุณกำลังทำงานอยู่ โดยทั่วไปแล้ว ข้อยกเว้น aTypeInitializationException จะเกิดขึ้นเมื่อคอนสตรัคเตอร์แบบคงที่ไม่สามารถสร้างอินสแตนซ์ของประเภทหรือสำหรับข้อยกเว้นที่ไม่สามารถจัดการได้ซึ่งเกิดขึ้นภายในคอนสตรัคเตอร์แบบ astatic สำหรับตัวสร้างสแตติกโดยนัยที่ไม่ได้กำหนดไว้อย่างชัดแจ้งในซอร์สโค้ด การแก้ไขปัญหาอาจต้องมีการตรวจสอบโค้ดภาษากลาง (IL)

  • การมีอยู่ของคอนสตรัคเตอร์แบบคงที่ช่วยป้องกันการเพิ่มแอตทริบิวต์ประเภท BeforeFieldInit สิ่งนี้จำกัดการเพิ่มประสิทธิภาพรันไทม์

  • ฟิลด์ที่ประกาศเป็นสแตติกอ่านอย่างเดียวอาจถูกกำหนดให้เป็นส่วนหนึ่งของการประกาศหรือในคอนสตรัคเตอร์แบบคงที่ เมื่อไม่ต้องการคอนสตรัคเตอร์แบบคงที่ที่ชัดเจน ให้เริ่มต้นฟิลด์สแตติกเมื่อมีการประกาศ แทนที่จะใช้คอนสตรัคเตอร์แบบคงที่เพื่อการเพิ่มประสิทธิภาพรันไทม์ที่ดีขึ้น

ตัวอย่าง

using System;
namespace DemoApplication{
   public class Program{
      static void Main(string[] args){
         Car user = new Car();
         Car user1 = new Car();
         Console.ReadLine();
      }
   }
   public class Car{
      static Car(){
         Console.WriteLine("Static constructor called");
      }
      public Car(){
         Console.WriteLine("Default constructor called");
      }
   }
}

ผลลัพธ์

Static constructor called
Default constructor called
Default constructor called

ในตัวอย่างข้างต้น เราจะเห็นว่า static constructor ถูกเรียกเพียงครั้งเดียว

ตัวอย่าง

using System;
using System.Threading;
namespace DemoApplication{
   public class Car{
      protected static readonly DateTime globalStartTime;
      protected int RouteNumber { get; set; }
      static Car(){
         globalStartTime = DateTime.Now;
         Console.WriteLine($"Static constructor called. Global start time:
         {globalStartTime.ToLongTimeString()}");
      }
      public Car(int routeNum){
         RouteNumber = routeNum;
         Console.WriteLine($"Car {RouteNumber} is created.");
      }
      public void Drive(){
         TimeSpan elapsedTime = DateTime.Now - globalStartTime;
         Console.WriteLine($"Car {this.RouteNumber} is starting its route
         {elapsedTime.Milliseconds} minutes after global start time
         {globalStartTime.ToShortTimeString()}.");
      }
   }
   class TestCar{
      static void Main(){
         Car car1 = new Car(1);
         Car car2 = new Car(2);
         car1.Drive();
         Thread.Sleep(25);
         car2.Drive();
         Console.ReadLine();
      }
   }
}

ผลลัพธ์

Static constructor called. Global start time:
7:09:06 AM
Car 1 is created.
Car 2 is created.
Car 1 is starting its route25 minutes after global start time7:09 AM.
Car 2 is starting its route50 minutes after global start time7:09 AM.