C # 9 ปัญหาประเภท Nullable
พิจารณาโค้ดต่อไปนี้ (VS 16.8.0 Preview 2.1 C # 9.0 preview):
#nullable enable
using System.Collections.Generic;
class Archive<T> where T : notnull
{
readonly Dictionary<string, T> Dict = new();
public T? GetAt(string key)
{
return Dict.TryGetValue(key, out var value) ? value : default;
}
}
class Manager
{
public int Age { get; set; }
}
class Main34
{
long F3()
{
Archive<long> a = new();
var johnAge = a.GetAt("john");
if (johnAge is null) return -1; // Error CS0037 Cannot convert null to 'long' because it is a non - nullable value type
return johnAge;
}
long F4()
{
Archive<Manager> a = new();
var johnAge = a.GetAt("john");
//if (johnAge is null) return -1;
return johnAge.Age; // Correct ! warning "Derefrencing of a possibly null reference" will be removed if line above unremarked
}
}
ฉันกำลังมีความเข้าใจเวลาที่ยาก / ที่อยู่ข้อผิดพลาดใน F3, ดูเหมือนว่าคอมไพเลอร์คิด johnAge มีlongไม่ได้long?(ที่ผมตรวจสอบโดยโฉบเหนือใน VS) แม้จะมีการกลับมาของArchive<T>.GetAtความเป็นอยู่T?
มีวิธีใดบ้างที่จะมีไฟล์เก็บถาวรทั่วไปซึ่งจะทำสิ่งที่ฉันต้องการ (วิธี GetAt ที่คืนค่า Nullable แม้ว่า T จะเป็นประเภทพื้นฐานที่ไม่เป็นโมฆะเช่น long)
คำตอบ
โดยพื้นฐานแล้วสิ่งนี้มาจากประเภทค่าที่เป็นโมฆะและประเภทการอ้างอิงที่เป็นโมฆะซึ่งแตกต่างกันมาก CLR ตระหนักถึงประเภทค่าที่เป็นโมฆะ แต่เท่าที่เกี่ยวข้องกับ CLR ประเภทการอ้างอิงที่เป็นโมฆะเป็นเพียง "ประเภทการอ้างอิงปกติโดยมีแอตทริบิวต์บอกคอมไพลเลอร์ว่าควรพิจารณาว่าเป็นโมฆะหรือไม่"
เมื่อTมีnotnullข้อ จำกัด ประเภทT?จะรวบรวมTใน IL มันต้อง - มันไม่สามารถคอมไพล์ได้Nullable<T>เนื่องจากมีNullable<T>ข้อ จำกัดTในการเป็นประเภทค่า
ดังนั้นการArchive<long>ที่GetAtวิธีการที่จะกลับ 0L ถ้าคีย์ไม่พบในพจนานุกรม - มันจะไม่ (และไม่สามารถ) กลับค่า null ของNullable<long>ซึ่งเป็นสิ่งที่รหัสของคุณในF3อย่างมีประสิทธิภาพคาดหวังว่า
คุณลักษณะ "ประเภทอ้างอิงที่เป็นโมฆะ" ทั้งหมดได้รับผลกระทบจากการพยายามเพิ่ม "แผ่นไม้อัด" ของการรับรู้ที่เป็นโมฆะในระบบประเภทที่โดยพื้นฐานแล้วไม่มี ฉันแน่ใจว่าตอนนี้รันไทม์และภาษาใหม่ได้รับการออกแบบร่วมกันตั้งแต่เริ่มต้นหรือไม่มันจะพยายามรวมสิ่งนี้ให้ใกล้ชิดมากขึ้น ตามที่เป็นอยู่ฉันเชื่อว่าคุณลักษณะนี้ยังคงมีคุณค่ามากมาย แต่แน่นอนว่ามันทำให้สิ่งต่างๆยุ่งยากมากเมื่อพูดถึงยาชื่อสามัญ