關于是否在C#中加入不可空引用類型的爭論

jopen 9年前發布 | 5K 次閱讀 C#

英文原文:Debate: Adding Non-nullable References to C#

來自微軟的 Mads Togersen 在近期所提出的一條提議,即在 C# 語言中加入對不可空引用類型的支持在 .NET 社區中引起了熱烈的爭論。人們對此提議的反應大相徑庭,既有人對此表示贊賞,也不乏傾向于保持現狀的意見。

在 Reddit 上,這條提議引起了大量關于向后兼容性方面的疑問。Strilanc 認為,如果應用了這一特性,按照這條提議的做法無法實現現有應用的平滑過渡

這條提議還有待改進,它對于保證二進制兼容性、源代碼兼容性以及現有代碼的漸進式過渡方面還存在著一些考慮不周的情況。

  1. 該提議造成了程序集級別上的意義轉變,每個引用類型的名稱意義都將變為不可空。它將一次性讓整個項目級別的代碼塊的意義發生巨大的改變,要順利地完成這一過程,需要付出大量的成本并承擔極高的風險。這一點非常糟糕。
  2. 該提議在泛型方面還有待改善,它完全沒有提及在大量的泛型代碼中將不允許使用 default (T)這一事實。這一點對于現有的代碼將產生怎樣的影響?可以采取哪些解決手段?那些確實需要這一功能的類型又將如何實現 default (T)的效果?這些問題都還沒有進行充分的探索。
  3. 這種方式豈不是會允許數組包含一些無效的初始值嗎?這種做法公然地違反了類型系統的意義,既然如此,何必還要將它硬塞進去呢?
  4. </ol> </blockquote>

    還有一方面的顧慮在于對于外部類庫的向后兼容性,正如 Maplemario 所說:

    那么問題來了。假設我要使用一個舊的類庫,其中的函數都返回類型T,無法它是否是可空的。現在,該提議產生了語言范式上的轉變,它將T視為不可空的 T類型,而我所調用的某個函數卻有可能返回 null(在編寫這個類庫時,這種做法是合法的)。如果這種場景在整個程序中是一個偶爾才需要進行測試的用例,那么在理想的情況下,項目文檔將指出這一點,而我在閱讀文檔后就知道應當在調用時進行空檢查。或者因為我記得這是一段陳舊的代碼,因此我將始終進行空檢查。而在實際情況下,由于“T即代表著不可空的T”,因此我無需再進行空檢查。如此一來,這段程序就會在我對空指針進行取值時崩潰。

    </blockquote>

    人們也在熱烈地討論這一提議的替代方案。用戶 00Davo 傾向于使用一種新的符號,以表示不可空類型

    我也樂于讓純粹的T類型總是代表不可空的引用,而只有T?才能夠接受空值,但這種改變對于向后兼容性來說就是一場惡夢。如果能引入一個全新的、明確的不可空引用符號,那么向后兼容性就會堅挺許多。比如使用T!符號,如何?

    </blockquote>

    而在有些人看來,實現這一提議會造成的問題過多了。Number127 建議將靜態分析作為一種替代方案

    遺憾的是,目前來看,如果要以一種優雅的方法引入不可空引用類型,會造成過多的兼容性問題。我認為最有希望的替代方案是在維持目前的類型系統的情況下,通過靜態分析技術以檢查某個引用是否能夠保證不為空。

    </blockquote>

    在 GitHub 的頁面上,人們同樣在討論靜態分析這一方案。Paulo Morgado 對此進行了更進一步的闡述,他表示這條提議其實就代表了靜態分析的使用

    如果我的理解沒錯,這條提議其實就是一種增強版的方法契約而已。編譯器在這里不會做出什么擔保,更不用說運行時了。編譯器所做的無非是對于那些聲明為可空的變量進行數據流的分析而已。

    </blockquote>

    在另一個話題中,Tomas Petricek 指出:這條提議必須考慮到其它 CLR 語言,例如F#:

    該提議能否詳細地說明一下如何在 CLR 級別保存可空的標注信息?(我猜測這些標注應當并不具有運行時的意義,它們只會表現為某種 .NET 
    attribute,或某種其它類型的元數據?)

    我希望未來某個版本的F#編譯器能夠辨識并理解這些標注信息,并定義某種“嚴格”模式,可空的類型在這種模式中將自動地暴露為 option<'T> 
    (或者差不多意思的某種類型)。

    </blockquote>

    對于不可空引用類型的爭論其實并不新鮮,在過去幾年中,對這一問題已經進行了多次討論。正如原微軟的首席開發者 Eric Lippert 所說,在一個已具有 15 年歷史的語言中添加不可空引用是一項浩大的工程

    來自: InfoQ
     本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!