ทำไมสิ่งนี้ถึงไม่คอมไพล์
int? number = true ? 5 : null;
ไม่สามารถระบุประเภทของนิพจน์เงื่อนไขได้เนื่องจากไม่มีการแปลงโดยนัยระหว่าง 'int' และ <null>
ทำไมสิ่งนี้ถึงไม่คอมไพล์
int? number = true ? 5 : null;
ไม่สามารถระบุประเภทของนิพจน์เงื่อนไขได้เนื่องจากไม่มีการแปลงโดยนัยระหว่าง 'int' และ <null>
คำตอบ:
ข้อมูลจำเพาะ (§7.14) กล่าวว่าสำหรับการแสดงออกเงื่อนไขb ? x : yมีสามความเป็นไปได้อย่างใดอย่างหนึ่งxและyทั้งสองมีประเภทและบางเงื่อนไขที่ดีจะพบเพียงคนเดียวxและyมีประเภทและบางเงื่อนไขที่ดีจะได้พบหรือข้อผิดพลาดเวลารวบรวม เกิดขึ้น ที่นี่ "เงื่อนไขที่ดีบางอย่าง" หมายถึงการแปลงบางอย่างที่เป็นไปได้ซึ่งเราจะได้รับรายละเอียดด้านล่าง
ทีนี้ลองหันไปหาส่วนที่เป็นส่วนประกอบของสเปค:
หากหนึ่งในนั้น
xและyมีประเภทและทั้งสองอย่างxและyแปลงได้โดยปริยายเป็นประเภทนั้นนั่นคือประเภทของการแสดงออกตามเงื่อนไข
ปัญหานี่คือสิ่งต่อไปนี้
int? number = true ? 5 : null;
ผลลัพธ์ที่มีเงื่อนไขหนึ่งรายการเท่านั้นที่มีประเภท นี่xเป็นintตัวอักษรและyเป็นnullที่ไม่ได้มีชนิดและnullไม่ได้แปลงสภาพไปยังปริยายint 1 ดังนั้นจึงไม่ตรงตาม "เงื่อนไขที่ดี" และเกิดข้อผิดพลาดในการคอมไพล์
มีอยู่สองวิธีรอบนี้:
int? number = true ? (int?)5 : null;
ที่นี่เรายังคงอยู่ในกรณีที่มีเพียงหนึ่งเดียวxและyมีประเภท โปรดทราบว่าnull ยังไม่มีประเภทคอมไพเลอร์จะไม่มีปัญหาใด ๆ กับสิ่งนี้เพราะ(int?)5และnullทั้งสองแปลงโดยปริยายเป็นint?(§6.1.4และ§6.1.5)
วิธีอื่นชัดเจน:
int? number = true ? 5 : (int?)null;
แต่ตอนนี้เรามีการอ่านที่แตกต่างกันประโยคหนึ่งในสเปคที่จะเข้าใจว่าทำไมถึงไม่เป็นไร:
หาก
xมีประเภทXและyมีประเภทYแล้ว
หากการแปลงโดยนัย (§6.1) มีอยู่ตั้งแต่
XถึงถึงYแต่ไม่ใช่จากYถึงXก็Yจะเป็นประเภทของนิพจน์เงื่อนไขหากการแปลงโดยนัย (§6.1) มีอยู่ตั้งแต่
YถึงถึงXแต่ไม่ใช่จากXถึงYก็Xจะเป็นประเภทของนิพจน์เงื่อนไขมิฉะนั้นจะไม่สามารถระบุประเภทนิพจน์ได้และเกิดข้อผิดพลาดในการรวบรวม
นี่xเป็นประเภทintและเป็นประเภทy int?ไม่มีการแปลงโดยปริยายจากเป็นint?ไปintแต่จะมีการแปลงนัยจากintไปดังนั้นประเภทของการแสดงออกคือint?int?
1 : โปรดทราบเพิ่มเติมว่าประเภทของด้านซ้ายมือจะถูกละเว้นในการกำหนดประเภทของนิพจน์เงื่อนไขซึ่งเป็นแหล่งที่มาของความสับสนทั่วไปที่นี่
new int?() (int?)null
DateTimeเมื่อจำเป็นต้องมี infact(DateTime?)
null ไม่มีประเภทที่สามารถระบุตัวตนได้ - เพียงแค่ต้องการการผลิตเพียงเล็กน้อยเพื่อให้มีความสุข:
int? number = true ? 5 : (int?)null;
int? number = true ? 5 : null as int?;
nullไม่มีประเภทที่สามารถระบุตัวตนได้ ปัญหาก็คือว่าไม่มีการแปลงโดยปริยายจากไปnull intรายละเอียดที่นี่
int? number = true ? 5 : (int?)null;และint? number = true ? (int?)5 : null;ทั้งรวบรวม !! เกา, เกา
เป็นคนอื่นได้กล่าวถึง 5 เป็นintและไม่สามารถแปลงไปโดยปริยายnullint
นี่คือวิธีอื่นในการแก้ไขปัญหา:
int? num = true ? 5 : default(int?);
int? num = true ? 5 : new int?();
int? num = true ? 5 : null as int?;
int? num = true ? 5 : (int?)null;
int? num = true ? (int?)5 : null;
int? num = true ? 5 as int? : null;
int? num = true ? new int?(5) : null;
นอกจากนี้ทุกที่ที่คุณดูแล้วคุณยังสามารถใช้int?Nullable<int>
ในบล็อกC# 9นี้ได้รับอนุญาต
พิมพ์เป้าหมายหรือไม่? และ
บางครั้งมีเงื่อนไข ?? และ?: นิพจน์ไม่มีประเภทที่แชร์ที่ชัดเจนระหว่างสาขา กรณีดังกล่าวล้มเหลวในวันนี้ แต่ C # 9.0 จะอนุญาตหากมีประเภทเป้าหมายที่สาขาทั้งสองแปลงเป็น:
Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type
หรือตัวอย่างของคุณ:
// Allowed in C# 9.
int? number = true ? 5 : null;