บางครั้งฉันเห็นตัวย่อในคุณสมบัติของผู้ทะเยอทะยาน เช่นสองประเภทนั้น:
public int Number { get; } = 0
public int Number => 0;
ใครช่วยได้โปรดบอกฉันว่ามีความแตกต่างระหว่างทั้งสอง พวกเขาทำงานอย่างไร ทั้งคู่เป็นแบบอ่านอย่างเดียวหรือไม่
บางครั้งฉันเห็นตัวย่อในคุณสมบัติของผู้ทะเยอทะยาน เช่นสองประเภทนั้น:
public int Number { get; } = 0
public int Number => 0;
ใครช่วยได้โปรดบอกฉันว่ามีความแตกต่างระหว่างทั้งสอง พวกเขาทำงานอย่างไร ทั้งคู่เป็นแบบอ่านอย่างเดียวหรือไม่
คำตอบ:
ใช่ทั้งคู่เป็นแบบอ่านอย่างเดียว แต่มีความแตกต่าง ในฟิลด์แรกจะมีเขตข้อมูลสำรองซึ่งเริ่มต้นเป็น 0 ก่อนที่ตัวสร้างจะดำเนินการ คุณสามารถเปลี่ยนค่าเฉพาะในตัวสร้างเช่นเดียวกับฟิลด์อ่านอย่างเดียวปกติ ผู้ทะเยอทะยานตัวเองเพียงส่งกลับค่าของสนาม
ในอันที่สอง getter จะส่งกลับค่า 0 ทุกครั้งโดยไม่มีฟิลด์ที่เกี่ยวข้อง
ดังนั้นเพื่อหลีกเลี่ยงการใช้คุณสมบัติที่ใช้งานอัตโนมัติหรือสมาชิกที่มีการแสดงออกเราจึงมี:
รุ่นแรก
private readonly int _number = 0;
public int Number { get { return _number; } }
รุ่นที่สอง
public int Number { get { return 0; } }
ตัวอย่างที่ชัดเจนของความแตกต่างอาจเห็นได้ดังนี้:
public DateTime CreationTime { get; } = DateTime.UtcNow;
public DateTime CurrentTime => DateTime.UtcNow;
หากคุณสร้างวัตถุเดียวCreationTime
คุณสมบัติของมันจะให้ผลลัพธ์เหมือนกันเสมอ - เนื่องจากมันถูกเก็บไว้ในเขตข้อมูลแบบอ่านอย่างเดียวซึ่งจะเริ่มต้นในการสร้างวัตถุ อย่างไรก็ตามทุกครั้งที่คุณเข้าถึงCurrentTime
คุณสมบัติที่จะทำให้DateTime.UtcNow
มีการประเมินผลดังนั้นคุณจะได้รับผลลัพธ์ที่แตกต่างกัน
ข้อแตกต่างอย่างหนึ่งคือเมื่อ0
ประเมินผล: เมื่อสร้างวัตถุหรือเมื่อใช้คุณสมบัติ
คุณสามารถเห็นสิ่งนี้ดีขึ้นด้วยคุณสมบัติ DateTime:
class SomeTestClass
{
public DateTime Start { get; } = DateTime.Now;
public DateTime Now => DateTime.Now;
}
Start
คุณสมบัติช่วยให้กลับมาในเวลาเดียวกัน (เมื่ออินสแตนซ์ที่ถูกสร้างขึ้น) ในขณะที่Now
การเปลี่ยนแปลงเพื่อให้สอดคล้องกับเวลาปัจจุบัน
คำอธิบาย :
รุ่นแรก ("เริ่มต้น") ระบุค่าเริ่มต้นที่อาจถูกเขียนทับโดยตัวสร้าง นี่คือการประเมินเพียงครั้งเดียว
รุ่นที่สอง ("ตอนนี้") ให้การแสดงออกซึ่งจะเป็น "ทะเยอทะยาน" ของคุณสมบัตินี้ ดังนั้นนี่คือการประเมินทุกครั้งที่มีการอ่านคุณสมบัติ ไม่มีแม้แต่ฟิลด์สำรองที่ตัวสร้างสามารถเขียนทับได้
นี่คือคุณสมบัติภาษา C # 6
ตัวอย่างแรก
public int Number { get; } = 0
ตัวอย่างแรกเป็นสถานที่ให้บริการอัตโนมัติทะเยอทะยานเท่านั้น เขตข้อมูลสำรองของคุณสมบัติอัตโนมัติ getter เท่านั้นจะถูกประกาศโดยนัยว่าเป็นแบบอ่านอย่างเดียว
ตัวอย่างที่สอง
public int Number => 0;
และเป็นตัวอย่างที่สองคือร่างกายแสดงออกสมาชิกฟังก์ชั่นคุณสมบัติเหมือน โปรดทราบว่าไม่มีget
คำหลักใด ๆ: มันมีนัยโดยการใช้ไวยากรณ์ของร่างกายนิพจน์
ทั้งสองเป็นแบบอ่านอย่างเดียว
random.NextInt()
หนึ่งตัวอย่างที่ดีคือถ้าคุณกลับ เวอร์ชันแรกจะประเมินว่าหนึ่งครั้งและจะมีค่าเท่ากันเสมอ ครั้งที่สองจะคืนค่าใหม่ทุกครั้ง