在开发中,我们经常会遇到 ui 需要依赖服务器数据的情况。直接用服务器返回的数据,可能会导致空引用、数据格式错误等问题。为了避免这些问题,我们可以使用一些设计模式,比如 接口、属性、简写属性表达式 和 松耦合,并通过 缺省值处理 来保证数据安全。
为什么要设计接口?
接口就像是一个 契约,它告诉类“你需要提供哪些功能”。在 ui 设计中,接口的作用是:定义必须提供的数据,而不关心数据的来源或结构。
设计接口的目的:
- 解耦:ui 层只关心接口,不关心数据的实现细节。这样即使数据格式改变,ui 层的代码也能不受影响。
- 保证数据可用性:通过接口确保每个属性都有一个有效的值,避免空引用错误。
- 统一缺省值处理:如果数据缺失,可以通过接口提供统一的缺省值,避免 ui 层重复编写空值检查的逻辑。
接口和属性的基本设计
接口定义了一些数据项,类通过实现接口来提供这些数据。这里的关键是:接口只定义“我能提供什么”,而不是“怎么提供”。
接口定义示例:
public interface iplayerviewdata
{
string titlename { get; }
string petname { get; }
string levelstr { get; }
}
接口的作用是:告诉 ui “我能拿到这些值”。但是,它并不关心这些值怎么从服务器拿到,也不管值可能会为空,接口只负责提供“我能拿到的值”。
实现接口:传统写法 vs 简写属性
在实现接口时,传统写法和简写表达式都可以用来提供属性:
public class playerviewdata : iplayerviewdata
{
private playerinfo _info;
public playerviewdata(playerinfo info)
{
_info = info; // 构造函数初始化
}
// 传统属性写法
public string titlename
{
get
{
if (_info == null || _info.titleinfo == null)
return "暂无称号"; // 如果数据缺失,返回默认值
return _info.titleinfo.name;
}
}
// 简写属性(表达式主体属性)
public string petname => _info?.petinfo?.petname ?? "无宠物";
public string levelstr => "lv." + (_info?.level ?? 1);
}
简写属性的优势:
- 简洁:用
=>简化了传统的get语法。 - 易读:代码更加清晰,尤其是对于只读属性,直接写表达式就行了。
如何处理数据缺失?(缺省值和安全访问)
在实际项目中,服务器返回的数据有可能为空。接口需要确保即使数据缺失,ui 层也能安全显示。
统一缺省值处理
你可以通过简写属性来保证数据的安全访问,并在数据为空时提供默认值:
public string titlename => _info?.titleinfo?.name ?? "暂无称号"; public string petname => _info?.petinfo?.petname ?? "无宠物";
??运算符提供了缺省值处理,如果数据为空(如titleinfo或petinfo为null),则返回默认字符串。
安全访问集合和可能为空的对象
为了避免集合为空时引发错误,我们可以使用 firstordefault() 方法,并结合 ?. 安全访问:
var attackentry = attrtables?.firstordefault(t => t.attname == "攻击");
?.确保在attrtables为null时,不会抛出空引用异常,而是返回null。
松耦合:ui 只关心接口,不关心数据实现
通过接口,我们可以保证 ui 层不会直接依赖数据结构。ui 层只关心接口定义的属性,而不需要知道数据是如何获取的。这就是 松耦合 的实现。
代码示例:
// 从服务器获取数据 playerinfo info = getplayerinfofromserver(); // 包装数据到接口 iplayerviewdata data = new playerviewdata(info); // ui 层使用接口更新显示 playerpanel.updateui(data);
- ui 只依赖接口:ui 层只关心“我能拿到什么显示值”,不需要知道数据是如何获取或处理的。
- ui 安全:即使
titleinfo为空,ui 也能正常显示缺省值"暂无称号"。
小结
| 概念 | 说明 |
|---|---|
| 接口属性 | 确保 ui 能安全读取数据,避免空引用 |
表达式属性 => | 简洁的属性写法,适合只读属性 |
firstordefault + ?. | 安全访问集合和可能为空的对象 |
| 松耦合 | ui 层只关心接口,不依赖数据实现 |
记忆口诀:
“接口保证能读,属性其实是函数,缺省值和 ?. 保证安全访问,ui 只依赖接口,不看内部结构”
以上就是在unity或c#项目中避免空引用和数据的解决方法的详细内容,更多关于unity或c#避免空引用和数据的资料请关注代码网其它相关文章!
发表评论