[英]C# 9 Nullable types issues
考慮以下(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?
有沒有辦法讓通用存檔可以做我想做的事情(即使 T 是不可為空的基本類型,即 long,也返回 Nullable 的 GetAt 方法)?
從根本上說,這歸結為可空值類型和可空引用類型非常非常不同。 CLR 知道可空值類型,但就 CLR 而言,可空引用類型只是“普通的引用類型,有一個屬性告訴編譯器是否應將其視為可為空的”。
當T
具有notnull
約束時,類型T?
只在 IL 中編譯為T
它必須 - 它不能編譯為Nullable<T>
,因為Nullable<T>
將T
約束為值類型。
因此,對於Archive<long>
,如果在字典中找不到鍵,則GetAt
方法將返回 0L - 它不會(也不能)返回Nullable<long>
的空值,這就是您的F3
代碼有效地期待。
整個“可空引用類型”功能的缺點是試圖在基本上沒有它的類型系統上添加可空感知的“貼面”。 我敢肯定,如果現在從頭開始設計新的運行時和語言,它會嘗試更緊密地統一這一點。 事實上,我相信這個特性仍然有很多價值——但是當涉及到泛型時,它肯定會讓事情變得非常棘手。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.