新聞

微軟.NET團隊說明,他們正在調整C#處理不安全(unsafe)程式碼的設計,讓可能影響記憶體安全的責任更明確地出現在程式碼中,並由編譯器協助檢查。該變更暫定列為C# 16功能,計畫在.NET 11提供預覽,並在.NET 12正式推出,初期在專案層級設定可選啟用,未來可能成為預設模式。

在既有C#模型中,unsafe主要用來建立允許使用指標相關功能的程式碼範圍,例如方法、型別或方法內部區塊。新模型調整後,unsafe不再只是允許開發者使用指標語法,而是用來標示一段程式碼涉及編譯器無法自行驗證的記憶體安全條件,也就是說,當成員簽章標上unsafe,代表該成員將特定安全義務傳遞給呼叫端。

新設計要求每個不安全操作都必須放在明確的unsafe區塊內,例如呼叫不安全方法,或是讀取、寫入指標指向的記憶體。若開發者能在方法內部先檢查輸入條件,完成風險處理,該方法對外仍可維持一般呼叫方式,但若無法處理,就必須把責任傳遞給呼叫端,呼叫端呼叫該成員時也必須放在unsafe區塊內。

該設計也會改變部分既有API揭露風險的方式,以Marshal.ReadByte這類API為例,過去這類方法可透過IntPtr讀取記憶體,但呼叫端不一定會因為方法簽章出現指標型別而受到限制。新模型擴大unsafe涵蓋範圍後,這類操作必須更清楚揭露呼叫端需要確保的條件,例如指標與位移量相加後,必須指向呼叫端有權讀取的有效記憶體位置。

除了語法規則,微軟也引入安全註解慣例。不安全成員應該附上專門的安全說明,寫明呼叫端必須滿足的條件,而方法內部則可用註解說明,開發者如何確認特定不安全操作所依賴的條件已經成立,分析器可協助找出缺少安全說明的情況。

該調整屬於編譯期規則變更,不會新增執行期檢查,也不會影響效能,違反新規則時,結果會出現編譯錯誤而不是警告。微軟表示,.NET執行期函式庫也會採用新模型,並計畫提供工具協助既有專案進行機械式調整,讓程式碼能先符合新規則,但安全條件的判斷與<safety>說明撰寫,仍需由開發者完成。