คำถามนี้เป็นหัวข้อของบล็อกของฉันเมื่อวันที่ 23 มิถุนายน 20112011 ขอบคุณสำหรับคำถามที่ยอดเยี่ยม!
ทีม C # กำลังพิจารณาเรื่องนี้ใน C # 7 ดูhttps://github.com/dotnet/roslyn/issues/5233สำหรับรายละเอียด
อัปเดต: ฟีเจอร์นี้ทำให้เป็น C # 7!
คุณถูก; .NET สนับสนุนวิธีการที่ส่งคืนการอ้างอิงที่ถูกจัดการไปยังตัวแปร .NET ยังสนับสนุนตัวแปรโลคัลที่มีการอ้างอิงที่ถูกจัดการกับตัวแปรอื่น ๆ (โปรดทราบว่า. NET ไม่สนับสนุนเขตข้อมูลหรืออาร์เรย์ที่มีการอ้างอิงที่มีการจัดการกับตัวแปรอื่น ๆ เนื่องจากมีความซับซ้อนมากเกินไปในเรื่องการรวบรวมขยะนอกจากนี้ยังมีประเภท "การจัดการอ้างอิงถึงตัวแปร" ด้วยไม่สามารถเปลี่ยนเป็นวัตถุได้ อาร์กิวเมนต์ประเภทเป็นประเภทหรือวิธีการทั่วไป)
ผู้แสดงความคิดเห็น "RPM1984" ด้วยเหตุผลบางอย่างขอให้มีการอ้างถึงข้อเท็จจริงนี้ RPM1984 ฉันขอแนะนำให้คุณอ่านข้อมูลจำเพาะ CLI พาร์ติชันที่ฉันส่วน 8.2.1.1, "ตัวชี้ที่มีการจัดการและประเภทที่เกี่ยวข้อง" สำหรับข้อมูลเกี่ยวกับคุณสมบัติของ. NET
เป็นไปได้ทั้งหมดที่จะสร้างเวอร์ชัน C # ซึ่งรองรับคุณสมบัติทั้งสองนี้ จากนั้นคุณสามารถทำสิ่งต่าง ๆ เช่น
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
แล้วเรียกมันด้วย
int a = 123;
int b = 456;
ref int c = ref Max(ref a, ref b);
c += 100;
Console.WriteLine(b); // 556!
ฉันรู้โดยสังเกตุว่าเป็นไปได้ที่จะสร้างรุ่น C # ที่รองรับคุณสมบัติเหล่านี้เพราะฉันได้ทำเช่นนั้นแล้วนั้น โปรแกรมเมอร์ขั้นสูงโดยเฉพาะผู้ที่โอนรหัส C ++ ที่ไม่มีการจัดการมักถามเราถึง C ++ เพิ่มเติมเช่นความสามารถในการทำสิ่งต่าง ๆ ที่มีการอ้างอิงโดยไม่ต้องออกค้อนใหญ่ ๆ ของการใช้พอยน์เตอร์และการตรึงหน่วยความจำทั่วทุกแห่ง โดยใช้การอ้างอิงที่มีการจัดการคุณจะได้รับประโยชน์เหล่านี้โดยไม่เสียค่าใช้จ่ายในการเพิ่มประสิทธิภาพการรวบรวมขยะ
เราได้พิจารณาคุณสมบัตินี้และใช้งานจริงมากพอที่จะแสดงต่อทีมภายในอื่น ๆ เพื่อรับข้อเสนอแนะของพวกเขา อย่างไรก็ตามในขณะนี้จากการวิจัยของเราเราเชื่อว่าคุณสมบัติไม่ต้องกว้างพออุทธรณ์หรือการใช้งานที่น่าสนใจกรณีที่จะทำให้มันเป็นจริงได้รับการสนับสนุนคุณลักษณะภาษา เรามีลำดับความสำคัญสูงกว่าอื่น ๆ และมีระยะเวลาและความพยายาม จำกัด ดังนั้นเราจะไม่ดำเนินการกับคุณลักษณะนี้เร็ว ๆ นี้
นอกจากนี้การทำอย่างถูกต้องจะต้องมีการเปลี่ยนแปลง CLR ตอนนี้ CLR ใช้วิธีการส่งคืนโดยอ้างอิงเป็นถูกต้องตามกฎหมายแต่ไม่สามารถพิสูจน์ได้เพราะเราไม่มีเครื่องมือตรวจจับที่ตรวจพบสถานการณ์นี้:
ref int M1(ref int x)
{
return ref x;
}
ref int M2()
{
int y = 123;
return ref M1(ref y); // Trouble!
}
int M3()
{
ref int z = ref M2();
return z;
}
M3 ส่งคืนเนื้อหาของตัวแปรโลคัลของ M2 แต่อายุการใช้งานของตัวแปรนั้นสิ้นสุดแล้ว! เป็นไปได้ที่จะเขียนเครื่องตรวจจับที่กำหนดการใช้ ref-return ที่ชัดเจนไม่ละเมิดความปลอดภัยของสแต็ก สิ่งที่เราจะทำคือเขียนตัวตรวจจับเช่นนั้นและหากตัวตรวจจับไม่สามารถพิสูจน์ความปลอดภัยของสแต็คได้เราจะไม่อนุญาตให้ใช้การส่งคืนค่าอ้างอิงในส่วนของโปรแกรมนั้น มันไม่ใช่งานที่ต้องทำมากนัก แต่มันเป็นภาระมากมายสำหรับทีมทดสอบเพื่อให้แน่ใจว่าเราได้รับทุกกรณีจริง ๆ เป็นเพียงอีกสิ่งหนึ่งที่เพิ่มค่าใช้จ่ายของคุณลักษณะไปยังจุดที่ตอนนี้ผลประโยชน์ไม่ได้มีค่าเกินดุล
หากคุณสามารถอธิบายให้ฉันทำไมมันเป็นสิ่งที่คุณต้องการคุณสมบัตินี้ผมจะขอบคุณที่ ยิ่งเรามีข้อมูลจากลูกค้าตัวจริงมากขึ้นเกี่ยวกับสาเหตุที่พวกเขาต้องการมันก็ยิ่งมีโอกาสมากขึ้นที่จะทำให้มันกลายเป็นผลิตภัณฑ์ในสักวันหนึ่ง มันเป็นฟีเจอร์น่ารักเล็ก ๆ น้อย ๆ และฉันต้องการให้ลูกค้าได้รับความสนใจอย่างเพียงพอ
(ดูคำถามที่เกี่ยวข้องเพิ่มเติมเป็นไปได้หรือไม่ที่จะส่งคืนการอ้างอิงถึงตัวแปรใน C #และฉันสามารถใช้การอ้างอิงภายในฟังก์ชัน C # เช่น C ++ ได้หรือไม่ )