หลักการตั้งชื่อ - ขีดล่างในตัวแปร C ++ และ C #


146

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



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

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

12
@ChaosPandion: จากนั้นอย่าอ่านมันเป็นคำสั่งแบบครอบคลุม "บางคน" ไม่ได้หมายถึง "ทั้งหมด" และ "ทั้งหมดบ่อยเกินไป" ไม่ได้หมายถึง "เสมอ" และบางทีคุณอาจเป็นข้อยกเว้นสำหรับประสบการณ์ของฉัน
Mike Seymour

17
ใน C ++ หลีกเลี่ยงการขีดเส้นใต้นำหน้า ในบริบทจำนวนมาก (เช่นที่ขอบเขตทั่วโลกเมื่ออักษรตัวใหญ่ดังต่อไปนี้ ฯลฯ ) พวกเขาจะถูกสงวนไว้สำหรับการดำเนินการและคุณมีความเสี่ยงที่จะมีการเหยียบย่ำแมโครบางส่วนเหนือพวกเขา ดังนั้นหากคุณต้องการให้พวกเขาทำให้พวกเขาต่อท้ายขีด
sbi

คำตอบ:


120

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

ใน C ++ เครื่องหมายขีดล่างมักจะระบุตัวแปรสมาชิกส่วนตัว

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

ก่อน:

private string _name;
public string Name
{
    get { return this._name; }
    set { this._name = value; }
}

หลังจาก:

public string Name { get; set; }

11
ยกเว้นสำหรับทีมที่ต้องการคุณสมบัติของพวกเขาจะไม่เปลี่ยนรูป
ChaosPandion

11
ตัวระบุที่ขึ้นต้นด้วยขีดล่างจะถูกสงวนไว้สำหรับคอมไพเลอร์ การใช้คำนำหน้าขีดเส้นใต้อาจขัดแย้งกับสัญลักษณ์คอมไพเลอร์
โทมัสแมตทิวส์

12
@Thomas Matthews - ไม่อยู่ใน C #
EMP

11
@ChaosPandion ฉันสมมติว่าสิ่งที่คุณหมายถึง "ไม่เปลี่ยนรูป" เป็นจริง "อ่านอย่างเดียว" public string Name { get; private set; }ซึ่งเป็นหนึ่งในกรณีที่สามารถใช้ จริงมันไม่ได้เปลี่ยนไม่ได้อย่างสมบูรณ์ แต่มันอยู่ที่นั่น
jdmichal

7
@Thomas ในบริบทของคลาสตัวระบุที่ขึ้นต้นด้วยเครื่องหมายขีดล่างและตามด้วยตัวพิมพ์ใหญ่ที่สงวนไว้ใน C ++ _varไม่ได้สงวนไว้
Tyler McHenry

84

เป็นแนวปฏิบัติที่ดีที่สุดที่จะไม่ใช้ UNDERSCORES ก่อนชื่อตัวแปรหรือชื่อพารามิเตอร์ใน C ++

ชื่อที่ขึ้นต้นด้วยขีดล่างหรือขีดล่างคู่จะถูกสงวนไว้สำหรับผู้พัฒนา C ++ ชื่อที่มีเครื่องหมายขีดเส้นใต้ถูกสงวนไว้เพื่อให้ไลบรารีทำงาน

หากคุณมีการอ่านที่มาตรฐานการเข้ารหัส C ++ คุณจะเห็นว่าในหน้าแรกมันบอกว่า:

"อย่าตั้งชื่อให้เกินความจริง แต่ใช้หลักการตั้งชื่อที่สอดคล้องกัน: มีเพียงสองสิ่งที่ต้องทำ: a) ไม่เคยใช้" ชื่อที่ไม่เหมาะสม "ที่เริ่มต้นด้วยขีดเส้นใต้หรือมีขีดล่างสองอัน; (p2, มาตรฐานการเข้ารหัส C ++, Herb Sutter และ Andrei Alexandrescu)

โดยเฉพาะอย่างยิ่งร่างการทำงานของ ISOระบุกฎจริง:

นอกจากนี้ตัวระบุบางตัวสงวนไว้สำหรับการใช้งานโดยการใช้งาน C ++ และจะไม่นำไปใช้เป็นอย่างอื่น ไม่จำเป็นต้องทำการวินิจฉัย (a) ตัวระบุแต่ละตัวที่มีเครื่องหมายขีดล่างคู่ __ หรือขึ้นต้นด้วยเครื่องหมายขีดล่างตามด้วยตัวอักษรตัวพิมพ์ใหญ่จะถูกสงวนไว้เพื่อการใช้งานสำหรับการใช้งานใด ๆ (b) ตัวระบุแต่ละตัวที่ขึ้นต้นด้วยขีดล่างจะถูกสงวนไว้สำหรับการนำไปใช้งานเพื่อใช้เป็นชื่อในเนมสเปซส่วนกลาง

เป็นวิธีปฏิบัติที่ดีที่สุดในการหลีกเลี่ยงการเริ่มต้นสัญลักษณ์ด้วยการขีดเส้นใต้ในกรณีที่คุณตั้งใจเดินเข้าไปในข้อ จำกัด ด้านบน

คุณสามารถเห็นได้ด้วยตัวคุณเองว่าทำไมการใช้ขีดล่างนั้นจึงเป็นหายนะเมื่อพัฒนาซอฟต์แวร์:

ลองรวบรวมโปรแกรม helloWorld.cpp แบบง่าย ๆ ดังนี้:

g++ -E helloWorld.cpp

คุณจะเห็นทุกสิ่งที่เกิดขึ้นในพื้นหลัง นี่คือตัวอย่าง:

   ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
   try
     {
       __streambuf_type* __sb = this->rdbuf();
       if (__sb)
  {
    if (__sb->pubsync() == -1)
      __err |= ios_base::badbit;
    else
      __ret = 0;
  }

คุณสามารถเห็นจำนวนชื่อขึ้นต้นด้วยเครื่องหมายขีดล่างคู่!

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

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


4
ไม่ใช่ชื่อที่ไม่ใช่โกลบอลหรือขอบเขตไฟล์และเริ่มต้นด้วยเครื่องหมายขีดล่างและอักษรตัวพิมพ์เล็กได้อย่างสมบูรณ์หรือไม่ ฉันทำเช่นนี้ตลอดเวลาเพราะมันสะอาดมากสำหรับกรณีเฉพาะเช่น: void A :: set_size (int _size) {size = _size; } คุณทำอะไรกับการใช้งานเล็กน้อยเช่นนี้?
tukra

3
ขีดเส้นใต้ตามด้วยตัวอักษรตัวพิมพ์เล็กได้รับอนุญาตในขอบเขตที่ไม่ใช่โกลบอล / ไฟล์ที่ฉันเชื่อ คุณสามารถแสดงให้ฉันดูว่าที่ไหนในมาตรฐานที่บอกว่าไม่ใช่ ปัญหาของการขีดเส้นใต้ต่อท้ายคือฉันใช้มันไปแล้วสำหรับ vars สมาชิกในบางครั้ง ดังนั้นฉันอาจมีฟังก์ชั่น 'int size ();' Member var 'int size_;' และอาร์กิวเมนต์ 'int _size' สิ่งนี้มีแนวโน้มที่จะครอบคลุมสิ่งต่าง ๆ อย่างดีและฉันไม่ได้เห็นทางเลือกที่ดีกว่า ฟังก์ชั่นตัวพิมพ์ใหญ่เป็นไปไม่ได้สำหรับยาชื่อสามัญที่ทำงานกับ STL สไตล์ 'this.size' ที่คน C # ดูเหมือนว่ามีข้อผิดพลาดเกิดขึ้นกับฉันเว้นแต่คุณจะใช้เพื่อเข้าถึงสมาชิกที่น่าเกลียด
tukra

7
ฉันเข้าใจบางคนที่ไม่ต้องการใช้ขีดเส้นใต้และตัวอักษรตัวเล็กเพราะอาจมีปัญหาในการรักษาสิ่งที่ถูกกฎหมาย มาตรฐาน C ++ อนุญาตให้ใช้แม้ว่าผู้เขียนบางคนไม่แนะนำให้ใช้ก็ตาม สำหรับฉันเนื่องจากถูกกฎหมายอย่างสมบูรณ์และไม่ได้จองไว้ฉันไม่เห็นเหตุผลใด ๆ ที่จะพิจารณาว่ามีความเสี่ยง ขอบคุณสำหรับความคิดเห็นของคุณ
tukra

3
@tukra: มันไม่ถูกกฎหมายอย่างสมบูรณ์ c ++ มาตรฐานเพียงช่วยให้คุณสามารถใช้ขีดเดียวตามด้วยตัวอักษรตัวพิมพ์เล็กอยู่ในขอบเขตท้องถิ่น โชคดี! :-)
Constantinos Glynos

4
ขอโทษ ฉันคิดว่าเราต้องผ่านการทำซ้ำคุณสมบัติเดิม ตัวระบุ C ++ ที่ขึ้นต้นด้วยขีดล่างตามด้วยตัวอักษรพิมพ์เล็กสามารถใช้ได้ในทุกขอบเขตนอกเหนือจากขอบเขตไฟล์ มันปลอดภัยและถูกกฎหมายในฟังก์ชั่นต้นแบบฟังก์ชั่น, คลาส, structs, สหภาพ, enums และทุกสิ่งที่คุณใส่ใน namespace หากคุณปฏิบัติตามแนวทางปฏิบัติทั่วไปในการวางโค้ดทั้งหมดในเนมสเปซคุณจะปลอดภัยอย่างสมบูรณ์
tukra

45

จริงๆแล้วการ_varประชุมนั้นมาจาก VB ไม่ใช่ C # หรือ C ++ (m _, ... เป็นอีกเรื่องหนึ่ง)

สิ่งนี้เกิดขึ้นเพื่อเอาชนะกรณีที่ไม่รู้สึกถึง VB เมื่อประกาศคุณสมบัติ

ตัวอย่างเช่นรหัสดังกล่าวเป็นไปไม่ได้ใน VB เพราะจะมีการพิจารณาuserและUserเป็นตัวระบุเดียวกัน

Private user As String

Public Property User As String
  Get
    Return user
  End Get
  Set(ByVal Value As String)
    user = value
  End Set
End Property

ดังนั้นเพื่อเอาชนะสิ่งนี้บางคนใช้การประชุมเพื่อเพิ่ม '_' ลงในฟิลด์ส่วนตัวเพื่อให้เป็นเช่นนี้

Private _user As String

Public Property User As String
  Get
    Return _user
  End Get
  Set(ByVal Value As String)
    _user = value
  End Set
End Property

เนื่องจากการประชุมจำนวนมากมีไว้สำหรับ. Net และเพื่อรักษาความสม่ำเสมอระหว่าง C # et VB.NET การประชุมพวกเขาใช้เหมือนกัน

ฉันพบข้อมูลอ้างอิงสำหรับสิ่งที่ฉันพูด: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices

Case Camel กับขีดเส้นใต้ชั้นนำ ใน VB.NET ให้ระบุ "Protected" หรือ "ส่วนตัว" เสมอห้ามใช้ "Dim" การใช้ "m_" นั้นไม่ได้รับการสนับสนุนเช่นเดียวกับการใช้ชื่อตัวแปรที่แตกต่างจากคุณสมบัติโดยเฉพาะกรณีโดยเฉพาะอย่างยิ่งกับตัวแปรที่ได้รับการป้องกันที่ละเมิดการปฏิบัติตามและจะทำให้ชีวิตของคุณเจ็บปวดหากคุณเขียนโปรแกรมใน VB.NET เช่นเดียวกับคุณ จะต้องตั้งชื่อสมาชิกของคุณบางอย่างที่แตกต่างจากคุณสมบัติ accessor / mutator ของรายการทั้งหมดที่นี่ขีดเส้นใต้เป็นข้อขัดแย้งเดียวเท่านั้น ฉันชอบมันมากกว่ากรณีอูฐที่ไม่เน้นเส้นตรงสำหรับตัวแปรส่วนตัวของฉันเพื่อที่ฉันจะได้ไม่ต้องรับรองชื่อตัวแปรด้วย "สิ่งนี้" เพื่อแยกความแตกต่างจากพารามิเตอร์ในคอนสตรัคเตอร์หรือที่อื่นที่ฉันอาจจะมีการชนกันของการตั้งชื่อ ด้วยความรู้สึกตัวพิมพ์เล็กของ VB.NET สิ่งนี้สำคัญกว่าเนื่องจากคุณสมบัติ accessor ของคุณมักจะมีชื่อเดียวกับตัวแปรสมาชิกส่วนตัวของคุณยกเว้นขีดล่าง เท่าที่ m_ ดำเนินไปมันเป็นเรื่องของสุนทรียภาพ ฉัน (และคนอื่น ๆ ) พบ m_ น่าเกลียดเพราะดูเหมือนว่ามีรูในชื่อตัวแปร มันเกือบจะน่ารังเกียจ ฉันเคยใช้มันใน VB6 ตลอดเวลา แต่นั่นเป็นเพราะตัวแปรไม่สามารถมีขีดล่างนำ ฉันไม่มีความสุขที่จะเห็นมันหายไป Microsoft แนะนำต่อ m_ (และตรง _) แม้ว่าพวกเขาจะทำทั้งสองอย่างในรหัส นอกจากนี้คำนำหน้าด้วย "m" แบบตรงก็จะหมด แน่นอนเนื่องจากพวกเขาใช้รหัสส่วนใหญ่ใน C # พวกเขาสามารถมีสมาชิกส่วนตัวที่แตกต่างกันเฉพาะในกรณีที่คุณสมบัติ คน VB ต้องทำอย่างอื่น แทนที่จะลองมาพร้อมกับกรณีพิเศษแบบภาษาต่อภาษาฉันขอแนะนำขีดเส้นใต้ชั้นนำสำหรับทุกภาษาที่จะสนับสนุน ถ้าฉันต้องการให้คลาสของฉันเป็นไปตาม CLS อย่างสมบูรณ์ฉันสามารถออกจากคำนำหน้าตัวแปร C # ที่ได้รับการป้องกัน อย่างไรก็ตามในทางปฏิบัติฉันไม่เคยกังวลเกี่ยวกับเรื่องนี้เพราะฉันเก็บตัวแปรสมาชิกที่อาจได้รับการป้องกันไว้เป็นส่วนตัวและจัดหา accessors และ mutators ที่ได้รับการป้องกันแทน ทำไม: สรุปการประชุมนี้ง่าย (ตัวละครหนึ่งตัว) ง่ายต่อการอ่าน (ดวงตาของคุณไม่ถูกรบกวนโดยตัวละครอื่น ๆ ) และหลีกเลี่ยงการตั้งชื่อการชนกันของตัวแปรระดับโพรซีเดอร์และคุณสมบัติระดับคลาส . ฉันขอแนะนำขีดเส้นใต้ชั้นนำสำหรับทุกภาษาที่จะรองรับ ถ้าฉันต้องการให้คลาสของฉันเป็นไปตาม CLS อย่างสมบูรณ์ฉันสามารถออกจากคำนำหน้าตัวแปร C # ที่ได้รับการป้องกัน อย่างไรก็ตามในทางปฏิบัติฉันไม่เคยกังวลเกี่ยวกับเรื่องนี้เพราะฉันเก็บตัวแปรสมาชิกที่อาจได้รับการป้องกันไว้เป็นส่วนตัวและจัดหา accessors และ mutators ที่ได้รับการป้องกันแทน ทำไม: สรุปการประชุมนี้ง่าย (ตัวละครหนึ่งตัว) ง่ายต่อการอ่าน (ดวงตาของคุณไม่ถูกรบกวนโดยตัวละครอื่น ๆ ) และหลีกเลี่ยงการตั้งชื่อการชนกันของตัวแปรระดับโพรซีเดอร์และคุณสมบัติระดับคลาส . ฉันขอแนะนำขีดเส้นใต้ชั้นนำสำหรับทุกภาษาที่จะรองรับ ถ้าฉันต้องการให้คลาสของฉันเป็นไปตาม CLS อย่างสมบูรณ์ฉันสามารถออกจากคำนำหน้าตัวแปร C # ที่ได้รับการป้องกัน อย่างไรก็ตามในทางปฏิบัติฉันไม่เคยกังวลเกี่ยวกับเรื่องนี้เพราะฉันเก็บตัวแปรสมาชิกที่อาจได้รับการป้องกันไว้เป็นส่วนตัวและจัดหา accessors และ mutators ที่ได้รับการป้องกันแทน ทำไม: สรุปการประชุมนี้ง่าย (ตัวละครหนึ่งตัว) ง่ายต่อการอ่าน (ดวงตาของคุณไม่ถูกรบกวนโดยตัวละครอื่น ๆ ) และหลีกเลี่ยงการตั้งชื่อการชนกันของตัวแปรระดับโพรซีเดอร์และคุณสมบัติระดับคลาส . ฉันไม่เคยกังวลเกี่ยวกับเรื่องนี้เพราะฉันเก็บตัวแปรสมาชิกที่อาจได้รับการป้องกันไว้เป็นส่วนตัวและจัดหา accessors และ mutators ที่ได้รับการป้องกันแทน ทำไม: สรุปการประชุมนี้ง่าย (ตัวละครหนึ่งตัว) ง่ายต่อการอ่าน (ดวงตาของคุณไม่ถูกรบกวนโดยตัวละครอื่น ๆ ) และหลีกเลี่ยงการตั้งชื่อการชนกันของตัวแปรระดับโพรซีเดอร์และคุณสมบัติระดับคลาส . ฉันไม่เคยกังวลเกี่ยวกับเรื่องนี้เพราะฉันเก็บตัวแปรสมาชิกที่อาจได้รับการป้องกันไว้เป็นส่วนตัวและจัดหา accessors และ mutators ที่ได้รับการป้องกันแทน ทำไม: สรุปสั้น ๆ ข้อตกลงนี้ง่าย (ตัวละครหนึ่งตัว) อ่านง่าย (ดวงตาของคุณไม่ถูกรบกวนโดยตัวละครอื่น ๆ ) และหลีกเลี่ยงการตั้งชื่อการชนกันของตัวแปรระดับโพรซีเดอร์และคุณสมบัติระดับคลาสคุณสมบัติระดับคลาส .


6

ผู้อ้างอิงคนแรก (R Samuel Klatchko) อ้างอิง: อะไรคือกฎเกี่ยวกับการใช้ขีดเส้นใต้ในตัวระบุ C ++? ซึ่งตอบคำถามเกี่ยวกับขีดล่างใน C ++ โดยทั่วไปแล้วคุณไม่ควรใช้ขีดเส้นใต้นำเนื่องจากถูกสงวนไว้สำหรับ implementer ของคอมไพเลอร์ของคุณ รหัสที่คุณเห็น_varอาจเป็นรหัสดั้งเดิมหรือรหัสที่เขียนโดยบุคคลที่โตขึ้นโดยใช้ระบบการตั้งชื่อแบบเก่าซึ่งไม่ทำให้เกิดการขีดเส้นใต้

ในฐานะที่เป็นคำตอบอื่น ๆ ก็จะใช้ใน C + + เพื่อระบุตัวแปรสมาชิกชั้นเรียน อย่างไรก็ตามมันไม่มีความหมายพิเศษเท่าที่นักตกแต่งหรือไวยากรณ์ ดังนั้นหากคุณต้องการใช้มันก็จะรวบรวม

ฉันจะออกจากการสนทนา C # กับคนอื่น ๆ


5

_var ไม่มีความหมายและทำหน้าที่เพียงเพื่อทำให้ง่ายต่อการแยกความแตกต่างว่าตัวแปรนั้นเป็นตัวแปรสมาชิกส่วนตัว

ใน C ++ การใช้การประชุม _var เป็นรูปแบบที่ไม่ดีเนื่องจากมีกฎที่ควบคุมการใช้ขีดล่างที่ด้านหน้าของตัวระบุ _var สงวนไว้เป็นตัวบ่งชี้ระดับโลกในขณะที่ _Var (ขีดล่าง + อักษรตัวใหญ่) จะถูกสงวนไว้ทุกที่ นี่คือสาเหตุที่ใน C ++ คุณจะเห็นผู้คนใช้การประชุม var_ แทน


4

คุณสามารถสร้างแนวทางการเข้ารหัสของคุณเอง เพียงเขียนเอกสารที่ชัดเจนสำหรับส่วนที่เหลือของทีม

การใช้ _field ช่วยให้ Intelilsense กรองตัวแปรคลาสทั้งหมดเพียงแค่พิมพ์ _

ฉันมักจะทำตามแนวทางของแบรดอดัมส์แต่แนะนำว่าอย่าใช้ขีดเส้นใต้


2

มาตรฐานการตั้งชื่อไมโครซอฟท์สำหรับ C # พูดว่าตัวแปรและพารามิเตอร์ควรใช้อูฐกรณีที่ต่ำกว่าแบบฟอร์มIE: paramNameมาตรฐานยังเรียกร้องให้เขตที่จะปฏิบัติตามรูปแบบเดียวกัน แต่ตอนนี้สามารถนำไปสู่รหัสไม่ชัดเจนเพื่อให้ทีมงานจำนวนมากเรียกร้องให้คำนำหน้าขีดที่จะปรับปรุงความชัดเจนIE: _fieldName


2

ด้วย C # แนวทางการออกแบบกรอบงานของ Microsoft แนะนำให้ไม่ใช้อักขระขีดล่างสำหรับสมาชิกสาธารณะ สำหรับสมาชิกส่วนตัวขีดเส้นใต้จะใช้ อันที่จริงแล้วJeffrey Richter (มักอ้างถึงในแนวทาง) ใช้ m_ เช่นและ "s_" สำหรับสมาชิกแบบคงที่ส่วนตัว

ส่วนตัวฉันใช้เพียง _ เพื่อทำเครื่องหมายสมาชิกส่วนตัวของฉัน "m_" และ "s_" verge บนสัญกรณ์ฮังการีซึ่งไม่เพียงขมวดคิ้วใน. NET แต่สามารถ verbose ค่อนข้างและฉันพบชั้นเรียนที่มีสมาชิกจำนวนมากยากที่จะทำการสแกนตาอย่างรวดเร็วตามตัวอักษร (จินตนาการ 10 ตัวแปรทั้งหมดเริ่มต้นด้วย m_) .


เนื่องจากสัญกรณ์ฮังการีระบุประเภทฉันไม่คิดว่าคุณจะพูดได้เลยว่า m / s ใกล้จะถึงมัน
Jerry Nixon

@ JerryNixon-MSFT เราจะระบุประเภทข้อมูลตัวแปรและประเภทการมองเห็นของตัวแปรเป็นสิ่งเดียวกันเมื่อพูดถึงแนวคิดของฮังการีหรือไม่?
Necro

1

ฉันใช้การตั้งชื่อ _var สำหรับตัวแปรสมาชิกของคลาสของฉัน มี 2 ​​เหตุผลหลักที่ฉันทำ:

1) มันช่วยฉันติดตามตัวแปรคลาสและตัวแปรฟังก์ชันท้องถิ่นเมื่อฉันอ่านโค้ดในภายหลัง

2) มันช่วยใน Intellisense (หรือระบบการเติมโค้ดอื่น ๆ ) เมื่อฉันกำลังมองหาตัวแปรคลาส การรู้ว่าอักขระตัวแรกมีประโยชน์ในการกรองผ่านรายการตัวแปรและวิธีการที่มีอยู่


1
มันเป็นความยุ่งยากในวิธีที่มีขนาดใหญ่กว่าที่จะพึ่งพาการโฮลอิน Intense หรือสแกนเพื่อดูว่ามีการกำหนด var ไว้ในเครื่องหรือไม่ ควรเลือก "__" สำหรับสถิตด้วยเหตุผลเดียวกันกับที่คุณพูดถึง แต่ขณะนี้ไม่ได้รับความนิยม
crokusek

1

เท่าที่เกี่ยวข้องกับภาษา C และ C ++ ไม่มีความหมายพิเศษในการขีดเส้นใต้ในชื่อ (เริ่มต้น, กลางหรือท้าย) มันเป็นเพียงชื่อตัวละครตัวแปรที่ถูกต้อง "อนุสัญญา" มาจากแนวทางปฏิบัติการเข้ารหัสภายในชุมชนการเข้ารหัส

ดังที่ระบุไว้แล้วโดยตัวอย่างต่าง ๆ ข้างต้น _ ในตอนต้นอาจหมายถึงสมาชิกส่วนตัวหรือได้รับการคุ้มครองของคลาสใน C ++

ขอผมเล่าประวัติบางอย่างที่อาจจะเป็นเรื่องสนุก ใน UNIX ถ้าคุณมีฟังก์ชั่นห้องสมุดแกน C และเคอร์เนลแบ็คเอนด์ที่คุณต้องการแสดงฟังก์ชั่นเคอร์เนลไปยังพื้นที่ผู้ใช้เช่นกัน _ จะติดอยู่ด้านหน้าของฟังก์ชั่นต้นขั้วที่เรียกฟังก์ชั่นเคอร์เนลโดยตรงโดยไม่ต้องทำอะไรเลย ตัวอย่างที่โด่งดังและคุ้นเคยที่สุดคือ exit () vs _exit () ภายใต้เคอร์เนลชนิด BSD และ SysV: นั่น exit () ทำสิ่งที่ผู้ใช้พื้นที่ก่อนที่จะเรียกบริการออกเคอร์เนลในขณะที่ _exit เพียงแมปไปยังบริการออกของเคอร์เนล

ดังนั้น _ ถูกใช้สำหรับสิ่งที่ "ท้องถิ่น" ในกรณีนี้ท้องถิ่นเป็นเครื่องจักรท้องถิ่น โดยทั่วไป _functions () ไม่สามารถพกพาได้ ในสิ่งที่คุณไม่ควรคาดหวังพฤติกรรมเดียวกันในแพลตฟอร์มต่างๆ

ตอนนี้สำหรับ _ ในชื่อตัวแปรเช่น

int _foo;

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

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


0

มันหมายถึงว่ามันเป็นเขตข้อมูลสมาชิกในชั้นเรียน


0

ไม่มีรูปแบบการตั้งชื่อแบบเฉพาะเจาะจง แต่ฉันเห็นแล้วว่าสำหรับสมาชิกส่วนตัว


0

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

อนุสัญญาการตั้งชื่ออย่างเป็นทางการของ C # ได้กำหนดชื่อตัวพิมพ์เล็กอย่างง่าย (ไม่มีขีดล่าง) สำหรับฟิลด์ส่วนตัว

ฉันไม่ทราบเกี่ยวกับอนุสัญญามาตรฐานสำหรับ C ++ แม้ว่าขีดล่างจะใช้กันอย่างแพร่หลาย


0

มันเป็นเพียงการประชุมที่โปรแกรมเมอร์บางคนใช้เพื่อทำให้ชัดเจนเมื่อคุณจัดการสมาชิกของคลาสหรือตัวแปรชนิดอื่น ๆ (พารามิเตอร์ท้องถิ่นกับฟังก์ชัน ฯลฯ ) การประชุมอื่นที่มีการใช้อย่างกว้างขวางสำหรับตัวแปรสมาชิกก็คือการนำหน้าชื่อด้วย 'm_'

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


0

มีเหตุผลที่ถูกต้องครบถ้วนในการใช้งานใน C #:หากรหัสต้องขยายได้จาก VB.NET เช่นกัน (มิฉะนั้นฉันจะไม่)

เนื่องจาก VB.NET ไม่ตรงตามตัวพิมพ์ใหญ่และตัวพิมพ์เล็กจึงไม่มีวิธีง่ายๆในการเข้าถึงfieldสมาชิกที่ได้รับการป้องกันในรหัสนี้:

public class CSharpClass
{
    protected int field;
    public int Field { get { return field; } }
}

เช่นนี้จะเข้าถึงตัวรับทรัพย์สินไม่ใช่ฟิลด์:

Public Class VBClass
    Inherits CSharpClass

    Function Test() As Integer
        Return Field
    End Function

End Class

Heck ฉันไม่สามารถเขียนfieldด้วยตัวพิมพ์เล็กได้ - VS 2010 เพียงแก้ไขต่อไป

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


0

ตอนนี้สัญกรณ์ที่ใช้ "นี่" เหมือนใน this.foobarbaz เป็นที่ยอมรับสำหรับตัวแปรสมาชิกคลาส C # มันแทนที่เครื่องหมาย "m_" เก่าหรือเพียงแค่เครื่องหมาย "__" มันทำให้โค้ดอ่านง่ายขึ้นเพราะไม่ต้องสงสัยเลยว่ามีการอ้างอิงอะไร


0

จากประสบการณ์ของฉัน (จำกัด อย่างแน่นอน) ขีดเส้นใต้จะระบุว่าเป็นตัวแปรสมาชิกส่วนตัว ดังที่กอลลัมกล่าวว่าสิ่งนี้จะขึ้นอยู่กับทีม


0

คำถามเก่า ๆ คำตอบใหม่ (C #)

การใช้เครื่องหมายขีดล่างสำหรับ C # ก็คือการใช้ DI ของ ASP NET Core (การฉีดพึ่งพา) readonlyตัวแปรส่วนตัวของคลาสที่กำหนดให้กับอินเทอร์เฟซที่ถูกฉีดในระหว่างการก่อสร้างควรเริ่มด้วยขีดล่าง ฉันเดาว่ามันเป็นการถกเถียงกันว่าจะใช้ขีดเส้นใต้สำหรับสมาชิกส่วนตัวทุกคนในชั้นเรียนหรือไม่

private readonly ILogger<MyDependency> _logger;

public MyDependency(ILogger<MyDependency> logger)
{
    _logger = logger;
}

-2

หลักการตั้งชื่อเช่นนี้มีประโยชน์เมื่อคุณอ่านรหัสโดยเฉพาะอย่างยิ่งรหัสที่ไม่ใช่ของคุณเอง แบบแผนการตั้งชื่อที่รัดกุมช่วยระบุตำแหน่งที่สมาชิกเฉพาะเจาะจงชนิดของสมาชิก ฯลฯ ทีมพัฒนาส่วนใหญ่ใช้ระเบียบการตั้งชื่อแบบง่าย ๆ และนำหน้าฟิลด์สมาชิกที่มีเครื่องหมายขีดล่าง ( _fieldName) ในอดีตฉันเคยใช้หลักการตั้งชื่อต่อไปนี้สำหรับ C # (ซึ่งเป็นไปตามอนุสัญญาของ Microsoft สำหรับรหัส. NET Framework ซึ่งสามารถเห็นได้ด้วย Reflector):

ฟิลด์อินสแตนซ์: m_fieldName ส
แตติกฟิลด์: s_fieldName
สาธารณะ / ป้องกัน / สมาชิกภายใน: PascalCasedName ()
สมาชิกส่วนตัว: camelCasedName ()

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


3
ที่จริงแล้ว Microsoft ไม่แนะนำให้ใช้คำนำหน้า m_, s_ อย่าใช้คำนำหน้าสำหรับชื่อฟิลด์ ตัวอย่างเช่นอย่าใช้ g_ หรือ s_ เพื่อแยกแยะสแตติกและฟิลด์ที่ไม่คงที่ msdn.microsoft.com/en-us/library/ms229012.aspx
Zied

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