ทำไมรหัสนี้ใช้งานได้? ฉันใช้ C # 8 กับ Visual Studio 2019
คุณได้ตอบคำถามของคุณเอง! เป็นเพราะคุณกำลังใช้ C # 8
กฎจาก C # 1 ถึง 7 คือ: ชื่อแบบง่ายไม่สามารถใช้เพื่อหมายถึงสองสิ่งที่แตกต่างในขอบเขตท้องถิ่นเดียวกัน (กฎจริงนั้นซับซ้อนกว่าเล็กน้อย แต่อธิบายว่าน่าเบื่อได้อย่างไรดูรายละเอียด C # สำหรับรายละเอียด)
ความตั้งใจของกฎนี้คือการป้องกันไม่ให้สถานการณ์ที่คุณกำลังพูดถึงในตัวอย่างของคุณที่จะกลายเป็นเรื่องง่ายที่จะสับสนเกี่ยวกับความหมายของท้องถิ่น โดยเฉพาะอย่างยิ่งกฎนี้ถูกออกแบบมาเพื่อป้องกันการสับสนเช่น:
class C
{
int x;
void M()
{
x = 123;
if (whatever)
{
int x = 356;
...
และตอนนี้เรามีสถานการณ์ที่ภายในร่างกายของM
, x
วิธีการทั้งสองและท้องถิ่นthis.x
x
แม้ว่าจะมีเจตนาดี แต่ก็มีปัญหามากมายเกี่ยวกับกฎนี้:
- มันไม่ได้ถูกนำไปใช้กับสเป็ค มีสถานการณ์ที่สามารถใช้ชื่อแบบง่ายเป็นได้ว่าทั้งประเภทและคุณสมบัติ แต่สิ่งเหล่านี้ไม่ได้ถูกตั้งค่าสถานะเป็นข้อผิดพลาดเสมอเนื่องจากตรรกะการตรวจหาข้อผิดพลาดนั้นมีข้อบกพร่อง (ดูด้านล่าง)
- ข้อความแสดงข้อผิดพลาดมีการใช้คำที่สับสนและมีการรายงานอย่างไม่สอดคล้องกัน มีข้อความแสดงข้อผิดพลาดที่แตกต่างกันหลายอย่างสำหรับสถานการณ์นี้ พวกเขาระบุผู้กระทำความผิดที่ไม่สอดคล้องกัน; นั่นคือบางครั้งการใช้งานภายในจะถูกเรียกออกบางครั้งด้านนอกและบางครั้งมันก็สับสน
ฉันใช้ความพยายามในการเขียนใหม่ของโรสลินเพื่อคัดออก; ฉันเพิ่มข้อความแสดงข้อผิดพลาดใหม่และทำให้ข้อความเก่าสอดคล้องกับที่รายงานข้อผิดพลาด อย่างไรก็ตามความพยายามนี้น้อยเกินไปสายเกินไป
ทีม C # ตัดสินใจสำหรับ C # 8 ว่ากฎทั้งหมดก่อให้เกิดความสับสนมากกว่าการป้องกันและกฎนั้นถูกยกเลิกจากภาษา (ขอบคุณ Jonathon Chase สำหรับการพิจารณาว่าเมื่อใดจะเกิดการเกษียณอายุ)
หากคุณสนใจที่จะเรียนรู้ประวัติของปัญหานี้และวิธีที่ฉันพยายามจะแก้ไขดูบทความเหล่านี้ที่ฉันเขียนเกี่ยวกับมัน:
https://ericlippert.com/2009/11/02/simple-names-are-not-so-simple/
https://ericlippert.com/2009/11/05/simple-names-are-not-so-simple-part-two/
https://ericlippert.com/2014/09/25/confusing-errors-for-a-confusing-feature-part-one/
https://ericlippert.com/2014/09/29/confusing-errors-for-a-confusing-feature-part-two/
https://ericlippert.com/2014/10/03/confusing-errors-for-a-confusing-feature-part-three/
ในตอนท้ายของส่วนที่สามฉันสังเกตเห็นว่ามีการโต้ตอบระหว่างคุณลักษณะนี้และคุณลักษณะ "สีสี" - นั่นคือคุณสมบัติที่ช่วยให้:
class C
{
Color Color { get; set; }
void M()
{
Color = Color.Red;
}
}
ที่นี่เราได้ใช้ชื่อง่ายๆColor
ในการอ้างถึงทั้งสองthis.Color
และประเภทแจกแจงColor
; ตามข้อกำหนดการอ่านที่เข้มงวดนี้ควรเป็นข้อผิดพลาด แต่ในกรณีนี้ข้อมูลจำเพาะผิดและความตั้งใจที่จะอนุญาตให้ใช้งานได้เนื่องจากรหัสนี้ไม่คลุมเครือและจะทำให้ผู้พัฒนาเปลี่ยนแปลง
ฉันไม่เคยเขียนบทความที่อธิบายถึงการโต้ตอบแปลก ๆ ทั้งหมดระหว่างกฎทั้งสองนี้และมันจะไม่มีจุดหมายสักหน่อยที่จะทำตอนนี้!
x
พารามิเตอร์ทั้งหมดของวิธีนั้นถูกย้ายออกจากขอบเขต ดูชาร์ปชาร์ปสำหรับตัวอย่าง