คุณใช้คำหลัก“ นี่” เมื่อใด [ปิด]


249

ฉันอยากรู้ว่าคนอื่นใช้คำหลักนี้อย่างไร ฉันมักจะใช้มันในตัวสร้าง แต่ฉันอาจใช้มันตลอดชั้นเรียนด้วยวิธีอื่น ตัวอย่างบางส่วน:

ในตัวสร้าง:

public Light(Vector v)
{
    this.dir = new Vector(v);
}

ที่อื่น ๆ

public void SomeMethod()
{
    Vector vec = new Vector();
    double d = (vec * vec) - (this.radius * this.radius);
}

2
ฉันพบตัวอย่างที่ดีเมื่อคุณต้องการ thisที่ MSDN โปรดไปที่ลิงก์นี้ ... ;-)
Matt

12
หากคุณต้องทำความเข้าใจและปรับให้เหมาะสมหรือเขียนคนอื่นส่วนใหญ่รหัสที่เขียนไม่ดีคุณยินดีที่จะมีthisหรือคุณสมบัติอื่น ๆ เพื่อให้จากลักษณะที่เรียบง่ายคุณรู้ขอบเขตของตัวแปร ลำดับชั้น) หรือsuper/ ตัวระบุbase) และการใช้ซินแท็กซ์ที่ใช้กันโดยทั่วไป_fooดูเหมือนว่าจะไม่ได้สวยหรูสำหรับตัวเอง กด_สำหรับ IntelliSense thisเป็นนานกว่าเข้าเวลามากขึ้น และทำไมตื๊อเลย! ด้วยฟังก์ชั่นการจัดรูปแบบการบันทึกอัตโนมัติของ eclipse ไม่จำเป็น_ในกรณีที่คุณลืมตัวระบุ
djmj

หลังจากอ่านคำตอบและความคิดเห็นด้านล่างเช่นเดียวกับการอ่านเอกสาร MSDN: docs.microsoft.com/en-us/previous-versions/visualstudio/ในคำหลักนี้ที่ยังไม่ได้รับการปรับปรุงใน 6 ปีฉันขอแนะนำ ไม่เคยใช้นี้คำหลัก มันไม่มีจุดหมาย อย่าทำให้พารามิเตอร์เป็นชื่อเดียวกันนั่นคือความสับสนและโง่เขลา ทำไมคุณจะทำเช่นนั้น? นอกจากนี้อย่าส่งตัวอย่างในการใช้สิ่งนี้มันยังสับสนและงี่เง่า
Yusha

คำตอบ:


218

มีการใช้คำหลักนี้หลายครั้งใน C #

  1. เพื่อให้สมาชิกที่มีคุณสมบัติที่ซ่อนอยู่มีชื่อคล้ายกัน
  2. เมื่อต้องการให้วัตถุผ่านตัวเองเป็นพารามิเตอร์ไปยังวิธีอื่น
  3. เมื่อต้องการให้วัตถุส่งคืนตัวเองจากวิธีการ
  4. เพื่อประกาศตัวทำดัชนี
  5. เพื่อประกาศวิธีการขยาย
  6. เพื่อส่งผ่านพารามิเตอร์ระหว่างตัวสร้าง
  7. ในการกำหนดค่าประเภท (struct) ของค่าภายใน
  8. เพื่อเรียกใช้วิธีการขยายในอินสแตนซ์ปัจจุบัน
  9. เพื่อร่ายเองไปอีกประเภทหนึ่ง
  10. ไปยังตัวสร้างห่วงโซ่ที่กำหนดไว้ในระดับเดียวกัน

คุณสามารถหลีกเลี่ยงการใช้งานครั้งแรกโดยไม่ต้องมีสมาชิกและตัวแปรท้องถิ่นที่มีชื่อเดียวกันในขอบเขตตัวอย่างเช่นโดยทำตามอนุสัญญาการตั้งชื่อทั่วไปและการใช้คุณสมบัติ (กรณี Pascal) แทนฟิลด์ (กรณีอูฐ) เพื่อหลีกเลี่ยงการชนกับตัวแปรท้องถิ่น กรณี). ใน C # 3.0 สาขาสามารถแปลงเป็นคุณสมบัติอย่างง่ายดายโดยใช้คุณสมบัติอัตโนมัติดำเนินการ


49
8. เพื่อเรียกใช้วิธีการขยายในอินสแตนซ์ปัจจุบัน ( this.Foo();จะใช้งานได้ แต่Foo()จะไม่ใช้)
Marc Gravell

4
((ICollection<T>)this).Add(bla)นอกจากนี้ยังจะโยนตัวเองกับประเภทอื่นตัวอย่างเช่นวิธีการดำเนินการอย่างชัดเจนจะถูกเรียกว่าเหมือน
nawfal

4
เพื่อก่อสร้างห่วงโซ่ให้กับตัวสร้างอื่นที่กำหนดไว้ในประเภทเดียวกัน public ClassName(...) : this(...).
Lasse V. Karlsen

1
@ และมันจะไม่ส่งผลกระทบต่อประสิทธิภาพ ณ รันไทม์ แต่อย่างใด สมมติว่าไม่มีความคลุมเครือเอาท์พุทคอมไพเลอร์ที่จะเหมือนกันไม่ว่าคุณจะเขียนเช่นหรือthis.someField = someValue someField = someValueมันอาจส่งผลกระทบต่อประสิทธิภาพของคอมไพเลอร์เนื่องจากคอมไพเลอร์จะแยกวิเคราะห์ซอร์สโค้ดแตกต่างกัน แต่ความแตกต่างใด ๆ จะเล็กน้อยมาก
phoog

7
คุณสามารถหลีกเลี่ยงปัญหาแรกได้ด้วยการเข้าถึงเขตข้อมูลผ่านทางคุณสมบัติเฉพาะเมื่อคุณปฏิบัติตามข้อกำหนดของสไตล์โดยที่คุณสมบัติไม่สามารถมีชื่อเดียวกับพารามิเตอร์ มันเกิดขึ้นที่การประชุมสไตล์ C # ที่แพร่หลายตรงตามข้อกำหนดนั้น อย่างไรก็ตามไม่ใช่ C # ทั้งหมดที่ถูกเขียนภายใต้การประชุมนั้น ไม่มีสิ่งใดที่มีอยู่ในตัวต่อคุณสมบัติที่จะทำให้thisคำหลักไม่จำเป็น พารามิเตอร์ตัวสร้างที่เรียกว่าxจะซ่อนสมาชิกที่เรียกxว่าสมาชิกเป็นเขตข้อมูลทรัพย์สินหรือเหตุการณ์สำหรับเรื่องนั้น
phoog

246

ฉันไม่ได้ตั้งใจให้เรื่องนี้ฟังดูน่าฟัง แต่มันก็ไม่สำคัญ

อย่างจริงจัง.

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

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

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


35
thisคำหลักที่มีความหมายความหมาย ดูความคิดเห็นของ @ JasonBunting ด้านล่าง คุณสร้างความสับสนให้โวหารมากเกินไปthisด้วยจุดประสงค์ที่แท้จริง คำพูดของคุณไม่เพียง แต่เป็นความผิดพลาด!
Dan Barowy

12
หากคุณมีโอกาสคุณอาจต้องการอ่านคำตอบของฉันอีกครั้ง ฉันพูดเกี่ยวกับการใช้งานในกรณีที่จำเป็นสำหรับความหมายที่ถูกต้อง คุณอาจต้องการดูคำถามต้นกำเนิด มันแสดงการใช้งานในตัวอย่างที่ไม่จำเป็นต้องใช้ความหมาย ดังนั้นฉันไม่แน่ใจว่าสิ่งที่ฉันพูดว่าเป็น "ผิด" คำตอบของฉันไม่แน่นอนอย่างแน่นอน
Scott Wisniewski

9
คุณรู้หรือไม่ว่าคำตอบของคุณฟังดูเป็นอย่างไร ระหว่างบรรทัดที่ฉันอ่าน "คุณกล้าถามคำถามเช่นนี้ได้อย่างไร" - นั่นไม่ใช่ความคิดสร้างสรรค์ของฉัน ไม่มีใครรู้ทุกอย่างนี่คือเหตุผลที่เรามี Stackoverflow: เพื่อช่วยเหลือผู้อื่นและรับความช่วยเหลือ บางหัวข้อที่คุณรู้จักบางคนรู้จักคนอื่น ช่วยเหลือซึ่งกันและกันอย่าทะเลาะกัน โปรดคิดเกี่ยวกับมัน
Matt

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

4
ฉันคิดว่าคุณอาจเข้าใจผิดจุดของฉัน ไม่ใช่ว่า "การมีสไตล์ที่สอดคล้องกัน" นั้นไม่ดี ฉันไม่ได้พูดอะไรกับสิ่งนั้น มันเป็นคำถามที่ op ของ "ควรแนะนำสไตล์ของฉัน 'นี้' เป็นคำนำหน้าสำหรับการเข้าถึงฟิลด์ทั้งหมดหรือไม่ " เป็นอิสระและแน่นอน
Scott Wisniewski

96

ฉันจะใช้มันเมื่อจำเป็นจริงๆเท่านั้นคือเมื่อตัวแปรอื่นแรเงาอีก เช่นที่นี่:

class Vector3
{
    float x;
    float y;
    float z;

    public Vector3(float x, float y, float z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

}

หรืออย่างที่ Ryan Fox ชี้ให้เห็นเมื่อคุณต้องการผ่านสิ่งนี้เป็นพารามิเตอร์ (ตัวแปรโลคัลมีความสำคัญเหนือกว่าตัวแปรสมาชิก)


6
ในกรณีนี้ทำไมไม่ให้ชื่อต่าง ๆ กับตัวแปรอินพุตของคอนสตรัคเตอร์?
wz366

54

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


9
แต่ถ้าคุณลืมที่จะใช้มันบางครั้งพวกเขาจะสับสน
ท่อง

2
@surfen ที่สามารถหลีกเลี่ยงได้ด้วยการตรวจสอบรูปแบบเพิ่มเติมเช่นใน Java คุณสามารถใช้ Checkstyle และเรียกใช้หลังจากการสร้างแบบเต็ม (และในภาษาย้ำที่นิยม / ภาษา OO ซ้ำจะมีเครื่องมือที่คล้ายกัน)
Maarten Bodewes

5
@surfen ราวกับว่าคุณลืมมันในกรณีที่ไม่ชัดเจน ฉันสามารถทะเลาะกันโดยการพูดว่า "แต่ถ้าคุณลืม ... "
Askolein

6
คนส่วนใหญ่ดูเหมือนจะไม่อ่านปรับหรือเขียนรหัสของคนอื่น! ผู้คัดเลือกคือเวลาและแรงจูงใจในการประหยัด! หากไม่มีการคัดเลือกแบบวิเศษก็จะเห็นว่าคุณเห็นโค้ดใด ๆ ดังนั้นคุณเสียเวลาเพียงตรวจสอบว่าตัวแปรเหล่านี้มาจากไหน
djmj

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

38

ฉันใช้ทุกครั้งที่ฉันอ้างถึงตัวแปรอินสแตนซ์แม้ว่าฉันไม่ต้องการ ฉันคิดว่ามันทำให้รหัสชัดเจนยิ่งขึ้น


ฉันต้องการแยกตัวแปรคลาสให้มากที่สุดเท่าที่จะทำได้ดังนั้นโค้ดจึงชัดเจนยิ่งขึ้น ฉันเคยใช้คำนำหน้า m_ (ตัวแปรสมาชิก) เช่นสตริงส่วนตัว m_name ตอนนี้ฉันเพิ่งใช้สิ่งนี้เช่นถ้าฉันมีการทดสอบคลาส {สตริงส่วนตัว a; someMethod สาธารณะ () {this.a = "foo"; }}
บรอดแบนด์

36

ฉันไม่อยากเชื่อทุกคนที่พูดว่าใช้มันเป็น "แนวปฏิบัติที่ดีที่สุด" เสมอ

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

แก้ไข: เอกสาร C # ใน "this" หมายถึงการใช้งานมากกว่าหนึ่งคำนอกเหนือจากที่ฉันได้กล่าวไว้สำหรับคำหลัก "this" - สำหรับการประกาศ indexers

แก้ไข: @ Juan: อืมมมผมไม่เห็นไม่สอดคล้องกันในงบของฉัน - มี 3 กรณีเมื่อฉันจะใช้ "คำนี้" (ตามที่บันทึกไว้ในเอกสาร C #) และผู้ที่มีเวลาจริงเมื่อคุณต้องการมัน การยึด "สิ่งนี้" ไว้หน้าตัวแปรในคอนสตรัคเตอร์เมื่อไม่มีเงาเกิดขึ้นเป็นเพียงแค่การกดแป้นพิมพ์และเสียเวลาของฉันเมื่ออ่านมันมันไม่มีประโยชน์


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

@ juan 10 ปีหลัง คุณยังคิดว่าการใช้ "สิ่งนี้" เป็นการฝึกฝนที่ดีหรือไม่? :)
Scott Adams

2
@ScottAdams ฉันยังเชื่อในความมั่นคงและความชัดเจนใช่
juan

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

27

ฉันใช้ทุกครั้งที่StyleCopบอกให้ฉันทำ StyleCopจะต้องเชื่อฟัง โอ้ใช่.


1
และ ReSharper บอกฉันว่าอย่าใช้มัน ชนิดของความสับสนเมื่อฉันใช้ทั้ง StyleCop และ ReSharper ในเวลาเดียวกัน :) แต่ฉันพึ่งพาคำตอบของ Coreys ด้านบนเพื่อใช้คำสำคัญ 'นี่' เมื่อจำเป็นจริงๆเท่านั้น
Gunnar

@Gunnar มีตัวเลือกในการปิดการใช้งานการกำจัดซ้ำซ้อน "นี้." ใน R #
Winger Sendon

@Em EmperorAiman ​​- ใช่ฉันรู้ ประเด็นของฉันคือเครื่องมือการจัดรูปแบบที่นิยมสองอย่างนั้นเป็นค่าเริ่มต้นแนะนำสิ่งต่าง ๆ สองแบบและอาจทำให้สับสน "จะเป็นหรือไม่เป็น ... " :)
Gunnar

11

ทุกครั้งที่คุณต้องการการอ้างอิงไปยังวัตถุปัจจุบัน

สถานการณ์ที่มีประโยชน์อย่างหนึ่งคือเมื่อวัตถุของคุณเรียกใช้ฟังก์ชันและต้องการส่งผ่านตัวมันเองเข้ามา

ตัวอย่าง:

void onChange()
{
    screen.draw(this);
}

7

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


5

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


5

การใช้งานที่ค่อนข้างหายากสำหรับคำหลักนี้ก็คือเมื่อคุณต้องการเรียกใช้การใช้งานอินเทอร์เฟซที่ชัดเจนจากภายในชั้นเรียนการใช้งาน นี่คือตัวอย่างที่วางแผนไว้:

class Example : ICloneable
{
    private void CallClone()
    {
        object clone = ((ICloneable)this).Clone();
    }

    object ICloneable.Clone()
    {
        throw new NotImplementedException();
    }
}

4

นี่คือเมื่อฉันใช้มัน:

  • การเข้าถึงวิธีการส่วนตัวจากภายในชั้นเรียน (เพื่อแยกความแตกต่าง)
  • ส่งผ่านวัตถุปัจจุบันไปยังวิธีอื่น (หรือเป็นวัตถุผู้ส่งในกรณีที่เกิดเหตุการณ์)
  • เมื่อสร้างวิธีการขยาย: D

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


4

[C ++]

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

แล้วคุณจะใช้มันเมื่อไหร่? ฉันเพิ่งได้ดูรอบรหัสสุ่มบางและพบว่าตัวอย่างเหล่านี้ (ฉันไม่ผ่านการตัดสินว่าสิ่งเหล่านี้เป็นสิ่งที่ดีสิ่งที่ต้องทำหรืออื่น ๆ ):

  • ผ่าน "ตัวคุณเอง" เพื่อฟังก์ชั่น
  • การกำหนด "ตัวคุณเอง" ให้กับตัวชี้หรืออะไรทำนองนั้น
  • การหล่อ, การขึ้น / ลง (ปลอดภัยหรืออย่างอื่น), การกำจัดความขุ่น, ฯลฯ
  • คอมไพเลอร์บังคับใช้ความกำกวม

3

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


3

ฉันใช้มันเมื่อในฟังก์ชั่นที่ยอมรับการอ้างอิงไปยังวัตถุประเภทเดียวกันฉันต้องการทำให้ชัดเจนอย่างสมบูรณ์ว่าวัตถุใดที่ฉันอ้างอิงถึงที่ไหน

ตัวอย่างเช่น

class AABB
{
  // ... members
  bool intersects( AABB other )
  {
    return other.left() < this->right() &&
           this->left() < other.right() &&

           // +y increases going down
           other.top() < this->bottom() &&
           this->top() < other.bottom() ;
  }
} ;

(VS)

class AABB
{
  bool intersects( AABB other )
  {
    return other.left() < right() &&
           left() < other.right() &&

           // +y increases going down
           other.top() < bottom() &&
           top() < other.bottom() ;
  }
} ;

AABB right()หมายถึงอะไร thisเพิ่มบิตของบ่อ


3

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

class MyClass {
    private int _x
    public MyClass() : this(5) {}
    public MyClass(int v) { _x = v;}
}

ฉันพบว่านี่เป็นคุณสมบัติที่มีประโยชน์อย่างยิ่งในบางโอกาส


2

ฉันมีนิสัยที่จะใช้มันอย่างอิสระใน Visual C ++ เพราะการทำเช่นนั้นจะทำให้ IntelliSense ที่ฉันกดปุ่ม '>' และฉันขี้เกียจ (และมีแนวโน้มที่จะพิมพ์ผิด)

แต่ฉันก็ยังใช้มันต่อไปเพราะฉันพบว่ามันมีประโยชน์ที่จะเห็นว่าฉันกำลังเรียกฟังก์ชั่นสมาชิกมากกว่าฟังก์ชั่นระดับโลก


1

ฉันมักจะขีดเส้นใต้ด้วย _ ดังนั้นไม่จำเป็นต้องใช้สิ่งนี้ นอกจากนี้ R # ยังมีแนวโน้มที่จะนำไปใช้ใหม่อีกครั้ง ...


1

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


1

ฉันใช้มันเมื่อจำเป็นเท่านั้นยกเว้นการดำเนินการแบบสมมาตรซึ่งเนื่องจาก polymorphism การโต้แย้งแบบเดี่ยวต้องถูกใส่ในวิธีการด้านเดียว:

boolean sameValue (SomeNum other) {
   return this.importantValue == other.importantValue;
} 

1

[C ++]

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

A a;
a = a;

ผู้ดำเนินการที่ได้รับมอบหมายของคุณจะถูกเขียน:

A& A::operator=(const A& a) {
    if (this == &a) return *this;

    // we know both sides of the = operator are different, do something...

    return *this;
}

1

this บนคอมไพเลอร์ C ++

คอมไพเลอร์ C ++ จะค้นหาสัญลักษณ์แบบเงียบ ๆ หากไม่พบในทันที บางครั้งเวลาส่วนใหญ่ดี:

  • ใช้วิธีการเรียนระดับ 'ถ้าคุณไม่ได้มากเกินไปในชั้นเรียนเด็ก
  • การส่งเสริมคุณค่าของประเภทเป็นประเภทอื่น

แต่บางครั้งคุณก็ไม่ต้องการให้คอมไพเลอร์เดา คุณต้องการให้คอมไพเลอร์รับสัญลักษณ์ที่ถูกต้องและไม่ใช่สัญลักษณ์อื่น

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

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

thisเหล่านี้เป็นสาเหตุที่ผมใช้

(§) มันยังคงเป็นปริศนาสำหรับฉัน แต่ตอนนี้ฉันสงสัยว่าข้อเท็จจริงที่ว่าคุณรวมส่วนหัว <windows.h> ไว้ในแหล่งที่มาของคุณหรือไม่นั่นเป็นเหตุผลว่าทำไมสัญลักษณ์ไลบรารี่ C ทั้งหมดที่สืบทอดกันมา

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


1

'นี้.' ช่วยค้นหาสมาชิกในคลาส 'this' ที่มีสมาชิกจำนวนมาก (โดยปกติจะเป็นเพราะโซ่ที่สืบทอดลึก)

การกดปุ่ม CTRL + Space ไม่ได้ช่วยสิ่งนี้เพราะมันมีประเภทด้วยเช่นกัน ที่ 'สิ่งนี้' รวมถึงสมาชิกเท่านั้น

ฉันมักจะลบมันเมื่อฉันมีสิ่งที่ฉันเป็นหลังจาก: แต่นี่เป็นเพียงสไตล์ของฉันทำลาย

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


1

ฉันใช้มันทุกครั้งที่ทำได้ ฉันเชื่อว่ามันทำให้โค้ดอ่านง่ายขึ้นและโค้ดที่อ่านได้มากขึ้นจะมีข้อบกพร่องน้อยลงและบำรุงรักษาได้มากขึ้น


1

เมื่อคุณเป็นนักพัฒนาซอฟต์แวร์จำนวนมากที่ทำงานบนฐานรหัสเดียวกันคุณต้องมีหลักเกณฑ์ / กฎบางประการ ฉันทำงานที่ใดเราต้องการใช้ 'สิ่งนี้' ในฟิลด์คุณสมบัติและกิจกรรม

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


0

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


0

ฉันใช้มันเพื่อเรียกใช้IntellisenseเหมือนกับJohnMcGแต่ฉันจะกลับไปและลบ "this->" เมื่อฉันทำเสร็จแล้ว ฉันทำตามแบบแผนของ Microsoft ในการเติมตัวแปรสมาชิกด้วย "m_" ดังนั้นการปล่อยไว้เป็นเอกสารก็จะซ้ำซ้อน


0

1 - สำนวน setter Java ทั่วไป:

 public void setFoo(int foo) {
     this.foo = foo;
 }

2 - เมื่อเรียกใช้ฟังก์ชันด้วยวัตถุนี้เป็นพารามิเตอร์

notifier.addListener(this);

0

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

คุณสามารถใช้thisในการแปลงชื่อที่ไม่ขึ้นอยู่กับชื่อขึ้นอยู่กับอาร์กิวเมนต์ภายในชั้นเรียนแม่แบบที่รับมาจากแม่แบบอื่น ๆ

template <typename T>
struct base {
   void f() {}
};

template <typename T>
struct derived : public base<T>
{
   void test() {
      //f(); // [1] error
      base<T>::f(); // quite verbose if there is more than one argument, but valid
      this->f(); // f is now an argument dependent symbol
   }
}

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

ในขั้นตอนนั้นหากไม่มีการแทนที่ชนิดจริงคอมไพเลอร์ก็แทบจะไม่มีข้อมูลของสิ่งที่base<T>จะเป็น (โปรดทราบว่าความเชี่ยวชาญของเทมเพลตฐานสามารถเปลี่ยนให้เป็นประเภทที่แตกต่างอย่างสิ้นเชิงแม้แต่ประเภทที่ไม่ได้กำหนด) ดังนั้นมันจึงสันนิษฐานว่าเป็นประเภท . ในขั้นตอนนี้การโทรfที่ไม่ขึ้นกับที่ดูเหมือนเป็นธรรมชาติกับโปรแกรมเมอร์คือสัญลักษณ์ที่คอมไพเลอร์ต้องค้นหาในฐานะสมาชิกของderivedหรือในการปิดล้อมเนมสเปซ - ซึ่งไม่ได้เกิดขึ้นในตัวอย่าง - และมันจะบ่น

การแก้ปัญหาคือการเปลี่ยนชื่อไม่ขึ้นอยู่กับชื่อfขึ้นอยู่กับ สิ่งนี้สามารถทำได้สองวิธีโดยระบุประเภทที่มีการนำไปใช้อย่างชัดเจน (- base<T>::fการเพิ่มbase<T>ทำให้สัญลักษณ์ขึ้นอยู่กับTผู้แปลและคอมไพเลอร์จะคิดว่ามันจะมีอยู่และเลื่อนการตรวจสอบจริงสำหรับรอบที่สองหลังจาก การทดแทนอาร์กิวเมนต์

วิธีที่สองคือตัวเรียงลำดับที่มากถ้าคุณสืบทอดจากเทมเพลตที่มีอาร์กิวเมนต์มากกว่าหนึ่งตัวหรือชื่อแบบยาวเพียงแค่เพิ่มthis->สัญลักษณ์ก่อนหน้า เนื่องจากคลาสเทมเพลตที่คุณใช้อยู่นั้นขึ้นอยู่กับอาร์กิวเมนต์ (ซึ่งสืบทอดมาจากbase<T>) this->นั้นขึ้นอยู่กับอาร์กิวเมนต์และเราได้รับผลลัพธ์เดียวกัน: this->fถูกตรวจสอบในรอบที่สองหลังจากการแทนที่พารามิเตอร์เทมเพลต


-2

คุณไม่ควรใช้ "สิ่งนี้" เว้นแต่ว่าคุณจะต้อง

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

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