คงที่อ่านได้อย่างเดียวเทียบกับ


1386

ฉันได้อ่านเกี่ยวกับconstและstatic readonlyฟิลด์ เรามีบางคลาสที่มีค่าคงที่เท่านั้น ใช้สำหรับสิ่งต่าง ๆ ในระบบของเรา ดังนั้นฉันสงสัยว่าการสังเกตของฉันถูกต้องหรือไม่:

ค่าคงที่เหล่านี้ควรเป็นค่าstatic readonlyสำหรับทุกสิ่งที่เป็นสาธารณะหรือไม่ และใช้constสำหรับค่าภายใน / การป้องกัน / ส่วนตัวเท่านั้น?

คุณแนะนำเมนูใด? ฉันควรจะไม่ใช้static readonlyฟิลด์ แต่ควรใช้คุณสมบัติหรือไม่


5
นี่เป็นกรณีเดียวที่น่าสนใจมากฉันเพิ่งพบในความโปรดปรานของstatic readonly: ลองใช้ const ภายในIEnumeratorซึ่งจะก่อให้เกิดunrecheable yieldและคุณจะได้รับหวั่น "รวบรวมข้อผิดพลาดภายใน" ผมไม่ได้ทดสอบรหัสนอก Unity3D แต่ผมเชื่อว่านี้เป็นทั้งขาวดำหรือ.NET ข้อผิดพลาด มันเป็นปัญหาc #อย่างไรก็ตาม
cregox

2
มีความเป็นไปได้ที่ซ้ำกันของconst และอ่านอย่างเดียวแตกต่างกันอย่างไร
nawfal

8
ข้อแตกต่างอื่นคือคุณสามารถใช้สตริง const ในสวิตช์ แต่ไม่ใช่สตริงแบบอ่านอย่างเดียวแบบคงที่
flagg19

7
static readonlyไม่สามารถใช้switch-caseคำสั่งเป็นcaseตัวแปรconstจำเป็นสำหรับวัตถุประสงค์นี้
Mostafiz Rahman

3
static readonlyไม่สามารถใช้เป็นพารามิเตอร์คุณลักษณะได้เช่นกัน
Dread Boy

คำตอบ:


940

public static readonlyทุ่งนานั้นผิดปกติเล็กน้อย public staticคุณสมบัติ (มีเพียงกget) จะเป็นเรื่องปกติมากขึ้น (อาจได้รับการสนับสนุนจากprivate static readonlyเขตข้อมูล)

constค่าจะถูกเขียนลงในไซต์การโทรโดยตรง นี่คือขอบสองครั้ง:

  • มันไม่มีประโยชน์อะไรถ้าค่านั้นมาจากรันไทม์บางทีจากการตั้งค่า
  • หากคุณเปลี่ยนค่าของ const คุณจะต้องสร้างไคลเอนต์ทั้งหมดอีกครั้ง
  • แต่มันอาจเร็วกว่านี้เนื่องจากจะหลีกเลี่ยงการเรียกเมธอด ...
  • ... ซึ่งบางครั้งอาจถูก JIT อินไลน์อยู่แล้ว

หากค่าจะไม่เปลี่ยนแปลงจากนั้น const เป็นเรื่องปกติ - Zeroฯลฯ ทำconst ที่เหมาะสม; p นอกเหนือจากนั้นstaticคุณสมบัติทั่วไป


13
ทำไมต้องเป็นทรัพย์สินเหนือทุ่ง ถ้าเป็นคลาสที่ไม่เปลี่ยนรูปฉันไม่เห็นความแตกต่างเลย
Michael Hedgpeth

73
@Michael - เหตุผลเดียวกันเช่นเคย; มันซ่อนการใช้งาน คุณอาจพบว่าคุณจำเป็นต้องโหลดแบบสันหลังยาวการกำหนดค่าตามรูปแบบซุ้มหรืออะไรก็ตาม ในความเป็นจริงทั้งสองมักจะดี ...
Marc Gravell

42
@CoffeeAddict ตามคำนิยามค่าคงที่ไม่ได้ดึงค่าจากไฟล์ปรับแต่ง มันถูกเผาเป็นตัวอักษรในเวลารวบรวม วิธีเดียวที่คุณสามารถใช้ค่าคงที่รันไทม์คือผ่านการไตร่ตรองเหนือเขตข้อมูล เวลาอื่น ๆ ที่คุณพยายามใช้คอมไพเลอร์จะแทนที่การใช้งานคงที่ของคุณสำหรับการใช้ตัวอักษรอยู่แล้ว เช่นถ้าวิธีการในรหัสของคุณใช้ค่าคงที่ 6 ค่าและคุณตรวจสอบเป็น IL จะไม่มีการเอ่ยถึงการค้นหาคงที่ใด ๆ ค่าแท้จริงจะถูกโหลดในแหล่งกำเนิด
Marc Gravell

37
@MarcGravell - ข้อควรระวัง: readonlyสาขาไม่สามารถนำมาใช้ในงบสวิตช์ / constกรณีแทนคุณต้องการให้เป็น
Luciano

7
@didibus การเปลี่ยนฟิลด์เป็นคุณสมบัติจะทำให้ API แตก เขตข้อมูลใน C # ทำหน้าที่เหมือนตัวแปรได้อย่างมีประสิทธิภาพในขณะที่คุณสมบัติใน C # เป็นตัวช่วยไวยากรณ์สำหรับการเขียนเมธอด getter และ / หรือเมธอด setter ความแตกต่างนี้มีความสำคัญเมื่อมีการประกอบอื่น ๆ ที่เกี่ยวข้อง หากคุณเปลี่ยนฟิลด์เป็นคุณสมบัติและแอสเซมบลีอื่น ๆ ขึ้นอยู่กับฟิลด์นี้แอสเซมบลีอื่น ๆ เหล่านั้นจะต้อง recompiled
Stephen Booher

237

ฉันจะใช้static readonlyถ้าผู้บริโภคอยู่ในการชุมนุมที่แตกต่างกัน มีconstและผู้บริโภคในสองประกอบที่แตกต่างกันเป็นวิธีที่ดีที่จะยิงตัวเองในการเดินเท้า


5
ดังนั้นฉันคิดว่าตามที่บางคนกล่าวถึงหรือพูดพาดพิงถึงมันก็ควรที่จะใช้ const สำหรับค่าที่เป็นค่าคงที่ที่รู้จักกันดีถ้าพวกเขาถูกเปิดเผยต่อสาธารณะมิฉะนั้นพวกเขาควรจะสงวนไว้สำหรับขอบเขตการเข้าถึงภายใน
jpierson

1
@Dio เหตุผลที่ยังคงมีอยู่เพราะมันไม่ใช่ปัญหาต่อ se - มันเป็นสิ่งที่ต้องระวัง แต่ความสามารถในการอินไลน์ const ข้ามขอบเขตการชุมนุมเป็นสิ่งที่ดีสำหรับประสิทธิภาพ มันเป็นเรื่องของการเข้าใจจริงๆว่า "ค่าคงที่" หมายถึง "มันจะไม่มีวันเปลี่ยนแปลง"
Michael Stum

1
@MichaelStum ตกลงฉันไม่ควรเรียกมันว่า "ปัญหา" ในสายงานของฉันฉันมี const และแบ่งปันข้ามแอสเซมบลี แต่ฉัน recompile สำหรับการปรับใช้หรือการจัดส่งรหัสแต่ละ อย่างไรก็ตามความจริงข้อนี้คุ้มค่าที่จะทราบ
Dio Phung

1
ดังนั้นโดยทั่วไปinternal constหรือpublic static readonlyขึ้นอยู่กับการมองเห็นที่ต้องการ
Iiridayn

2
@Iiridayn ใช่นั่นไม่ใช่วิธีที่ดีในการดู มีบางกรณีที่ต้องพิจารณา (เช่นหากใช้ Reflection หรือหากจำเป็นต้องใช้ค่าในแอตทริบิวต์) และมีการใช้งานที่ถูกต้องสำหรับpublic const(เช่นส่วนใด ๆ ของมาตรฐานทุกครั้งที่ฉันทำงานกับ XML จะมี ไฟล์เนมสเปซที่มีพวงpublic const string)) แต่โดยทั่วไปแล้วpublic constควรใช้งานหลังจากพิจารณาผลกระทบที่ถูกต้องเท่านั้น
Michael Stum

199

มีสิ่งที่เกี่ยวข้องอีกสองสามข้อที่ควรสังเกต:

const int

  • จะต้องเริ่มต้น
  • การเริ่มต้นต้องมีเวลารวบรวม

int แบบอ่านอย่างเดียว

  • สามารถใช้ค่าเริ่มต้นโดยไม่ต้องเริ่มต้น
  • การเริ่มต้นสามารถทำได้ในเวลาทำงาน (แก้ไข: ภายในตัวสร้างเท่านั้น)

39
ภายในctorเท่านั้น
Amit Kumar Ghosh

1
ไม่เฉพาะภายในนวกรรมิก แต่ในการประกาศด้วย ( docs.microsoft.com/en-us/dotnet/csharp/language-reference/ … )
deChristo

176

นี่เป็นเพียงส่วนเสริมของคำตอบอื่น ๆ ฉันจะไม่ทำซ้ำพวกเขา (ตอนนี้สี่ปีต่อมา)

มีสถานการณ์ที่ a constและไม่ใช่สมาชิกมีความหมายที่แตกต่างกัน ตัวอย่างเช่น:

const int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

พิมพ์ออกมาTrueในขณะที่:

static readonly int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

Falseเขียน

เหตุผลก็คือเมธอดx.Equalsมีสองโอเวอร์โหลดหนึ่งอันที่ใช้ใน a short( System.Int16) และอีกอันที่ใช้object( System.Object) ตอนนี้คำถามคือหนึ่งหรือทั้งสองใช้กับyอาร์กิวเมนต์ของฉัน

เมื่อyเป็นค่าคงที่เวลาคอมไพล์ (ตามตัวอักษร) constกรณีมันจะกลายเป็นสิ่งสำคัญที่มีอยู่การแปลงโดยปริยายจาก int เพื่อ shortให้intมีค่าคงที่และหากคอมไพเลอร์ C # ตรวจสอบว่าค่าของมันอยู่ในช่วงของshort( ซึ่ง42ก็คือ) ดูการแปลงนิพจน์ค่าคงที่โดยนัยในข้อกำหนดภาษา C # ดังนั้นจึงต้องคำนึงถึงภาระทั้งสองอย่าง เกินพิกัดEquals(short)เป็นที่ต้องการ (ใด ๆshortเป็นobjectแต่ไม่ทั้งหมดobjectมีshort) ดังนั้นyจะถูกแปลงเป็นshortและใช้งานเกินพิกัด แล้วEqualsเปรียบเทียบสองของค่าที่เหมือนกันและที่ให้shorttrue

เมื่อyไม่ได้เป็นคงไม่มีนัยแปลงจากintการshortที่มีอยู่ นั่นเป็นเพราะโดยทั่วไปแล้วintอาจมีขนาดใหญ่เกินไปที่จะเข้าshortกันได้ (มีการแปลงอย่างชัดเจนแต่ฉันไม่ได้พูดEquals((short)y)ดังนั้นมันจึงไม่เกี่ยวข้องกัน) เราเห็นว่ามีการใช้งานเกินEquals(object)หนึ่งครั้งเท่านั้น ดังนั้นจะบรรจุกล่องไปy objectจากนั้นEqualsจะไปเปรียบเทียบSystem.Int16กับและตั้งแต่ประเภทเวลาทำงานไม่ได้เห็นด้วยที่จะให้ผลผลิตSystem.Int32false

เราสรุปว่าในบางกรณี (หายาก) การเปลี่ยนconstประเภทสมาชิกเป็นstatic readonlyเขตข้อมูล (หรือวิธีอื่นเมื่อเป็นไปได้) สามารถเปลี่ยนพฤติกรรมของโปรแกรม


17
นอกจากนี้ยังเป็นคำตอบที่ดี ฉันต้องการเพิ่มการแปลงประเภทข้อมูลที่เหมาะสมและแนวทางอื่น ๆ ที่คล้ายกัน (เช่นลองจับ ฯลฯ ) ควรเป็นแก่นของโปรแกรมเมอร์ที่มีประสบการณ์และไม่เหลือไว้ในคอมไพเลอร์ อย่างไรก็ตามฉันได้เรียนรู้สิ่งใหม่จากที่นี่ ขอบคุณ.
Uknight

ว้าวฉันได้เขียนโปรแกรมใน C # เป็นเวลานานและฉันไม่เคยคิดเลยว่า const int ที่อยู่ในช่วงของการย่ออาจถูกแปลงเป็นแบบสั้น ฉันต้องบอกว่ามันค่อนข้างแปลก ฉันรัก C # แต่สิ่งที่ไม่สอดคล้องเหล่านี้แปลกที่ดูเหมือนจะไม่เพิ่มคุณค่ามากนัก แต่เพิ่มพลังสมองที่จำเป็นมากมายเพื่อพิจารณาอย่างต่อเนื่องอาจน่ารำคาญโดยเฉพาะอย่างยิ่งสำหรับผู้เริ่มต้น
Mike Marynowski

@MikeMarynowski จริงเพียงพอ แต่ฉันคิดว่าพวกเขาทำกฎนั้น (ด้วยเหตุผลอื่น ๆ ) เพื่อทำให้คำสั่งนั้นshort x = 42;ถูกกฎหมาย เพราะมีคุณมีintคือที่แท้จริงซึ่งจะเปิดเข้ามาโดยปริยาย42 short xแต่พวกเขาอาจ จำกัด สิ่งนี้ไว้ที่ตัวอักษรตัวเลขเท่านั้น อย่างไรก็ตามพวกเขาเลือกที่จะให้สิ่งต่าง ๆ เช่นshort x = y;ที่yถูกกำหนดเป็นconst int y = 42;แล้วพวกเขาก็ลงเอยด้วย
Jeppe Stig Nielsen

87

สิ่งหนึ่งที่ควรทราบคือconstถูก จำกัด ประเภทดั้งเดิม / ค่า (ข้อยกเว้นเป็นสตริง)


30
ที่จริงแล้วconstสามารถใช้สำหรับประเภทอื่น ๆ ได้เช่นกันยกเว้นว่าจะต้องเริ่มต้นให้เป็นโมฆะซึ่งทำให้มันไร้ประโยชน์ :)
nawfal

6
ยกเว้นในขณะที่System.Exception? :)
Memet Olsen

4
@nawfal อย่างแม่นยำมากขึ้นเท่านั้นค่าชนิดที่constสามารถนำมาใช้เป็นsbyte, byte, short, ushort, int, uint, long, ulong,char , float, double, decimal, boolบวกใด ๆenumประเภท constไม่สามารถนำมาใช้สำหรับค่าประเภทอื่น ๆ เช่นDateTimeหรือหรือTimeSpan BigIntegerนอกจากนี้ยังไม่สามารถใช้สำหรับIntPtrstruct ได้ (พิจารณาว่าเป็นชนิด "ดั้งเดิม" โดยบางประเภทคำดั้งเดิมจะสับสนใน C #) ↵↵ constสามารถนำมาใช้สำหรับทุกประเภทของการอ้างอิง หากเป็นประเภทstringค่าสตริงใด ๆ สามารถระบุได้ nullมิฉะนั้นค่าที่จะต้อง
Jeppe Stig Nielsen

@JeppeStigNielsen - ฉันเพิ่งโต้เถียงกับservyเกี่ยวกับเรื่องนี้ - เขาชี้ให้เห็นว่าคุณสามารถทำอะไร (มูลค่าและการอ้างอิงชนิด) โดยใช้const defaultสำหรับstructประเภทมันเป็นตัวอย่างที่สมาชิกทุกคนตั้งค่าเป็นค่าเริ่มต้น
Wai Ha Lee

28

อ่านอย่างเดียวแบบคงที่ : ค่าสามารถเปลี่ยนแปลงได้ผ่านตัวstaticสร้างที่รันไทม์ แต่ไม่ผ่านฟังก์ชั่นสมาชิก

อย่างต่อเนื่อง : staticโดยค่าเริ่มต้น ค่าไม่สามารถเปลี่ยนแปลงได้จากทุกที่ (Ctor, ฟังก์ชั่น, รันไทม์และอื่น ๆ ไม่มีที่)

อ่านอย่างเดียว : ค่าสามารถเปลี่ยนแปลงได้ผ่านตัวสร้างที่รันไทม์ แต่ไม่ผ่านฟังก์ชั่นสมาชิก

คุณสามารถดูได้ที่ repo ของฉัน: C # ทรัพย์สินประเภท


1
ข่าวร้าย ... ลิงค์เสีย!
Fer R


ตัวอย่างที่ดีของสยามভাই :)
Muhammad Ashikuzzaman

25

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

การอ้างอิง MSDN แบบสั้นและชัดเจนที่นี่


16

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 สามารถระบุเจตนาได้ สิ่งนี้ทำให้เกิดพฤติกรรมการกำหนดเวอร์ชันที่ดีขึ้นและประสิทธิภาพที่ดีขึ้น


12

การตั้งค่าของฉันคือการใช้constทุกครั้งที่ทำได้ซึ่งดังที่ได้กล่าวไว้ข้างต้นจะ จำกัด เฉพาะการแสดงออกที่แท้จริงหรือสิ่งที่ไม่ต้องการการประเมินผล

ถ้าฉันเจอกับข้อ จำกัด นั้นฉันก็เลือกที่จะอ่านได้อย่างเดียวโดยมีข้อแม้หนึ่งข้อ ฉันมักจะใช้สถานที่ให้บริการสาธารณะคงมีทะเยอทะยานและสนับสนุนเอกชนคงอ่านได้อย่างเดียวฟิลด์เป็นมาร์คกล่าวถึงที่นี่


7

Const: Const คืออะไรนอกจาก "ค่าคงที่" ซึ่งเป็นตัวแปรที่ค่าคงที่ แต่ในเวลารวบรวม และจำเป็นต้องกำหนดค่าให้กับมัน โดยค่าเริ่มต้น const คงที่และเราไม่สามารถเปลี่ยนค่าของตัวแปร const ได้ตลอดโปรแกรมทั้งหมด

แบบคงที่ ReadOnly:ค่าตัวแปรชนิดคงที่อ่านได้อย่างเดียวสามารถกำหนดได้ที่รันไทม์หรือกำหนดในเวลารวบรวมและการเปลี่ยนแปลงที่รันไทม์ แต่ค่าของตัวแปรนี้สามารถเปลี่ยนแปลงได้ในตัวสร้างสแตติกเท่านั้น และไม่สามารถเปลี่ยนแปลงได้อีก มันสามารถเปลี่ยนได้เพียงครั้งเดียวที่รันไทม์

อ้างอิง: c-sharpcorner


6

ฟิลด์สแตติกแบบอ่านอย่างเดียวจะมีประโยชน์เมื่อเปิดเผยให้แอสเซมบลีอื่นค่าที่อาจเปลี่ยนแปลงในรุ่นที่ใหม่กว่า

ตัวอย่างเช่นสมมติว่าแอสเซมบลีXเปิดเผยค่าคงที่ดังนี้:

public const decimal ProgramVersion = 2.3;

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

อีกวิธีหนึ่งในการดูสิ่งนี้คือค่าใด ๆ ที่อาจเปลี่ยนแปลงในอนาคตนั้นไม่คงที่ตามคำจำกัดความดังนั้นจึงไม่ควรแสดงเป็นค่าเดียว


3

const:

  1. ควรให้มูลค่าเมื่อมีการประกาศ
  2. รวบรวมเวลาคงที่

อ่านเท่านั้น:

  1. สามารถกำหนดค่าได้ตามการประกาศหรือในระหว่างรันไทม์โดยใช้ตัวสร้างค่าอาจแตกต่างกันไปขึ้นอยู่กับตัวสร้างที่ใช้
  2. ค่าคงที่เวลาทำงาน

3

Const : ค่าตัวแปร const ต้องกำหนดพร้อมกับการประกาศและหลังจากนั้นจะไม่เปลี่ยนแปลง const คงที่โดยปริยายดังนั้นโดยไม่ต้องสร้างอินสแตนซ์ของคลาสเราสามารถเข้าถึงได้นี่มีค่า ณ เวลารวบรวม

อ่านเท่านั้น : ค่าตัวแปรอ่านได้เดียวที่เราสามารถกำหนดได้ในขณะที่ประกาศเช่นเดียวกับการใช้ตัวสร้างที่รันไทม์ ตัวแปรแบบอ่านอย่างเดียวไม่สามารถเข้าถึงได้โดยไม่มีอินสแตนซ์ของคลาส

คงที่อ่านได้อย่างเดียว : ค่าตัวแปรอ่านอย่างเดียวแบบคงที่เราสามารถกำหนดในขณะที่ประกาศเช่นเดียวกับผ่านตัวสร้างแบบคงที่ แต่ไม่ได้มีตัวแปรตัวสร้างอื่น ๆ นอกจากนี้เรายังสามารถเข้าถึงได้โดยไม่ต้องสร้างอินสแตนซ์ชั้นเรียน

คงอ่านได้อย่างเดียวจะเป็นทางเลือกที่ดีกว่าถ้าเราต้องใช้ตัวแปรในการประกอบที่แตกต่างกันโปรดตรวจสอบรายละเอียดในลิงค์ด้านล่าง

https://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/


คุณช่วยบอกฉันหน่อยได้ไหมว่าทำไมคุณถึงลงคำตอบฉันจึงสามารถอัพเดทตัวเองได้ที่นี่
user1756922

ไม่ใช่ DV แต่อาจเป็นได้ว่าคำตอบนี้ไม่ได้เพิ่มอะไรเลยกับคำตอบที่ครอบคลุมอยู่แล้วที่นี่
Marc L.

แน่นอนจำไว้ใน Java ย้อนกลับไปในช่วงปลายยุค 90 ที่เรามีในโครงการหลายคนผลิตขวดที่แตกต่างกันกับไฟล์ระดับที่ทำงานร่วมกัน (อ้างอิงซึ่งกันและกัน) และสตริง const สาธารณะมีปัญหารุ่นเนื่องจากพวกเขาถูกคัดลอกรอบ
จอร์จ Birbilis

2

มีความแตกต่างเล็กน้อยระหว่างฟิลด์ const และสแตติกแบบอ่านอย่างเดียวใน C # .Net

const ต้องเริ่มต้นด้วยค่าในเวลารวบรวม

const เป็นค่าคงที่เริ่มต้นและจะต้องเริ่มต้นด้วยค่าคงที่ซึ่งไม่สามารถแก้ไขได้ในภายหลัง มันไม่สามารถใช้กับประเภทข้อมูลทั้งหมด สำหรับอดีต DateTime มันไม่สามารถใช้กับประเภทข้อมูล DateTime

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public static readonly string Name = string.Empty; //No error, legal

อ่านได้อย่างเดียวสามารถประกาศเป็นแบบคงที่ แต่ไม่จำเป็น ไม่จำเป็นต้องเริ่มต้น ณ เวลาที่ประกาศ ค่าสามารถกำหนดหรือเปลี่ยนแปลงได้โดยใช้ Constructor หนึ่งครั้ง ดังนั้นจึงมีความเป็นไปได้ที่จะเปลี่ยนค่าของเขตข้อมูลแบบอ่านอย่างเดียวหนึ่งครั้ง (ไม่สำคัญถ้าเป็นค่าคงที่หรือไม่) ซึ่งไม่สามารถใช้ค่าคงที่ได้


0

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

ตัวแปรแบบอ่านอย่างเดียวคือฟิลด์ที่สามารถเปลี่ยนแปลงได้ภายใต้เงื่อนไขเฉพาะ

พวกเขาสามารถเริ่มต้นได้เมื่อคุณประกาศพวกเขาเหมือนค่าคงที่ แต่โดยปกติแล้วพวกเขาจะเริ่มต้นได้ในระหว่างการก่อสร้างวัตถุภายในตัวสร้าง

ไม่สามารถเปลี่ยนแปลงได้หลังจากการเตรียมใช้งานเกิดขึ้นในเงื่อนไขที่กล่าวถึงข้างต้น

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

ความแตกต่างที่สำคัญอีกอย่างหนึ่งก็คือค่าคงที่อยู่ในคลาสในขณะที่ตัวแปรอ่านอย่างเดียวเป็นของอินสแตนซ์!


0

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

ในแง่ของการจัดสรรหน่วยความจำอย่างน้อยกับสตริง (เป็นประเภทการอ้างอิง) ดูเหมือนว่าจะไม่มีความแตกต่างในการที่ทั้งสองถูก interned และจะอ้างอิงหนึ่งอินสแตนซ์ interned

โดยส่วนตัวแล้วค่าเริ่มต้นของฉันเป็นแบบสแตติกแบบอ่านอย่างเดียวเนื่องจากมีความหมายและสมเหตุสมผลมากกว่าสำหรับฉันโดยเฉพาะอย่างยิ่งเนื่องจากค่าส่วนใหญ่ไม่จำเป็นต้องใช้ในการรวบรวม และโดยวิธีการทางสถิติสาธารณะอ่านอย่างเดียวไม่ได้ผิดปกติหรือผิดปกติเลยเป็นรัฐคำตอบที่ทำเครื่องหมาย: ตัวอย่างเช่นSystem.String.Emptyเป็นหนึ่ง


0

ความแตกต่างระหว่างการประกาศอีกconstและคงอ่านได้อย่างเดียวอยู่ในจัดสรรหน่วยความจำ

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

ในทางกลับกันฟิลด์const "เป็นของอินสแตนซ์ของประเภท

หากหน่วยความจำของ deallocation เป็นสิ่งสำคัญมากสำหรับคุณชอบที่จะใช้const หากความเร็วใช้สแตติกแบบอ่านอย่างเดียว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.