在Unity或C#項目中避免空引用和數(shù)據(jù)的解決方法
在開發(fā)中,我們經常會遇到 UI 需要依賴服務器數(shù)據(jù)的情況。直接用服務器返回的數(shù)據(jù),可能會導致空引用、數(shù)據(jù)格式錯誤等問題。為了避免這些問題,我們可以使用一些設計模式,比如 接口、屬性、簡寫屬性表達式 和 松耦合,并通過 缺省值處理 來保證數(shù)據(jù)安全。
為什么要設計接口?
接口就像是一個 契約,它告訴類“你需要提供哪些功能”。在 UI 設計中,接口的作用是:定義必須提供的數(shù)據(jù),而不關心數(shù)據(jù)的來源或結構。
設計接口的目的:
- 解耦:UI 層只關心接口,不關心數(shù)據(jù)的實現(xiàn)細節(jié)。這樣即使數(shù)據(jù)格式改變,UI 層的代碼也能不受影響。
- 保證數(shù)據(jù)可用性:通過接口確保每個屬性都有一個有效的值,避免空引用錯誤。
- 統(tǒng)一缺省值處理:如果數(shù)據(jù)缺失,可以通過接口提供統(tǒng)一的缺省值,避免 UI 層重復編寫空值檢查的邏輯。
接口和屬性的基本設計
接口定義了一些數(shù)據(jù)項,類通過實現(xiàn)接口來提供這些數(shù)據(jù)。這里的關鍵是:接口只定義“我能提供什么”,而不是“怎么提供”。
接口定義示例:
public interface IPlayerViewData
{
string TitleName { get; }
string PetName { get; }
string LevelStr { get; }
}
接口的作用是:告訴 UI “我能拿到這些值”。但是,它并不關心這些值怎么從服務器拿到,也不管值可能會為空,接口只負責提供“我能拿到的值”。
實現(xiàn)接口:傳統(tǒng)寫法 vs 簡寫屬性
在實現(xiàn)接口時,傳統(tǒng)寫法和簡寫表達式都可以用來提供屬性:
public class PlayerViewData : IPlayerViewData
{
private PlayerInfo _info;
public PlayerViewData(PlayerInfo info)
{
_info = info; // 構造函數(shù)初始化
}
// 傳統(tǒng)屬性寫法
public string TitleName
{
get
{
if (_info == null || _info.TitleInfo == null)
return "暫無稱號"; // 如果數(shù)據(jù)缺失,返回默認值
return _info.TitleInfo.Name;
}
}
// 簡寫屬性(表達式主體屬性)
public string PetName => _info?.PetInfo?.PetName ?? "無寵物";
public string LevelStr => "Lv." + (_info?.Level ?? 1);
}
簡寫屬性的優(yōu)勢:
- 簡潔:用
=>簡化了傳統(tǒng)的get語法。 - 易讀:代碼更加清晰,尤其是對于只讀屬性,直接寫表達式就行了。
如何處理數(shù)據(jù)缺失?(缺省值和安全訪問)
在實際項目中,服務器返回的數(shù)據(jù)有可能為空。接口需要確保即使數(shù)據(jù)缺失,UI 層也能安全顯示。
統(tǒng)一缺省值處理
你可以通過簡寫屬性來保證數(shù)據(jù)的安全訪問,并在數(shù)據(jù)為空時提供默認值:
public string TitleName => _info?.TitleInfo?.Name ?? "暫無稱號"; public string PetName => _info?.PetInfo?.PetName ?? "無寵物";
??運算符提供了缺省值處理,如果數(shù)據(jù)為空(如TitleInfo或PetInfo為null),則返回默認字符串。
安全訪問集合和可能為空的對象
為了避免集合為空時引發(fā)錯誤,我們可以使用 FirstOrDefault() 方法,并結合 ?. 安全訪問:
var attackEntry = attrTables?.FirstOrDefault(t => t.AttName == "攻擊");
?.確保在attrTables為null時,不會拋出空引用異常,而是返回null。
松耦合:UI 只關心接口,不關心數(shù)據(jù)實現(xiàn)
通過接口,我們可以保證 UI 層不會直接依賴數(shù)據(jù)結構。UI 層只關心接口定義的屬性,而不需要知道數(shù)據(jù)是如何獲取的。這就是 松耦合 的實現(xiàn)。
代碼示例:
// 從服務器獲取數(shù)據(jù) PlayerInfo info = GetPlayerInfoFromServer(); // 包裝數(shù)據(jù)到接口 IPlayerViewData data = new PlayerViewData(info); // UI 層使用接口更新顯示 playerPanel.UpdateUI(data);
- UI 只依賴接口:UI 層只關心“我能拿到什么顯示值”,不需要知道數(shù)據(jù)是如何獲取或處理的。
- UI 安全:即使
TitleInfo為空,UI 也能正常顯示缺省值"暫無稱號"。
小結
| 概念 | 說明 |
|---|---|
| 接口屬性 | 確保 UI 能安全讀取數(shù)據(jù),避免空引用 |
表達式屬性 => | 簡潔的屬性寫法,適合只讀屬性 |
FirstOrDefault + ?. | 安全訪問集合和可能為空的對象 |
| 松耦合 | UI 層只關心接口,不依賴數(shù)據(jù)實現(xiàn) |
記憶口訣:
“接口保證能讀,屬性其實是函數(shù),缺省值和 ?. 保證安全訪問,UI 只依賴接口,不看內部結構”
以上就是在Unity或C#項目中避免空引用和數(shù)據(jù)的解決方法的詳細內容,更多關于Unity或C#避免空引用和數(shù)據(jù)的資料請關注腳本之家其它相關文章!
相關文章
C#使用Spire.Doc將HTML轉換為文本的代碼實現(xiàn)
在 .NET 開發(fā)中,將 HTML 轉換為純文本是一項常見任務,無論是從網頁中提取內容、處理 HTML 郵件,還是生成輕量級的文本報告,使用 C# 進行 HTML 到文本的轉換就顯得尤為重要,本文將介紹如何使用該庫在 C# 中將 HTML 轉換為純文本,需要的朋友可以參考下2025-10-10
DevExpress實現(xiàn)自定義GridControl中按鈕文字內容的方法
這篇文章主要介紹了DevExpress實現(xiàn)自定義GridControl中按鈕文字內容的方法,需要的朋友可以參考下2014-08-08
C#去除DataTable重復數(shù)據(jù)的三種方法
這篇文章主要介紹了C#去除DataTable重復數(shù)據(jù)的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-02-02
C#通過配置文件動態(tài)修改web.config內容的操作步驟
這篇文章主要介紹了C#通過配置文件動態(tài)修改web.config內容的操作步驟,文中通過圖文結合的方式介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-03-03

