属性绑定数据绑定思路
/// 方案对比:
/// 表现层监听消息--->数据层改变发消息---->表现层收到消息,表现层改变
/// 表现层监听消息--->数据层改变会自动发消息(少写了发消息的代码),表现层改变
/// 优点:少写了发消息的代码
可以说是另外一种思路,但是也可以其他办法解决,自动发消息这个过程,这里我实现了个
核心代码
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using UnityEngine; /// <summary> /// 属性绑定 /// </summary> /// <typeparam name="T"></typeparam> public class BindableProperty<T> { private List<Action> changeList = new List<Action>(); private T _data; public BindableProperty(T data) { _data = data; } public T data { get { return _data; } set { _data = value; DispatchAll(); } } public void AddListener(Action ac) { if (!changeList.Contains(ac)) { changeList.Add(ac); } else { Debug.LogWarning("重复监听"); } } public void RemoveListener(Action ac) { if (changeList.Contains(ac)) { changeList.Remove(ac); } else { Debug.LogWarning("移除的消息不存在"); } } public void ClearListener() { changeList.Clear(); Debug.Log("清理成功"); } private void DispatchAll() { foreach (var item in changeList) { item(); } } } /// <summary> /// List /// 使用了ReadOnlyCollection作为保护,使用IReadOnlyList也是可以 /// 通过Add Remove Update Clear 对数据进行操作 /// </summary> /// <typeparam name="T"></typeparam> public class BindableList<T> { private List<Action> changeList = new List<Action>(); private List<T> _data; public BindableList() { _data = new List<T>(); } public ReadOnlyCollection<T> data { get { return _data.AsReadOnly(); } private set { } } public void Add(T t) { _data.Add(t); DispatchAll(); } public void Remove(T t) { if (_data.Contains(t)) { _data.Remove(t); DispatchAll(); } } public void Clear() { _data.Clear(); DispatchAll(); } public void Update(List<T> _list) { _data = _list; DispatchAll(); } public void AddListener(Action ac) { if (!changeList.Contains(ac)) { changeList.Add(ac); } else { Debug.LogWarning("重复监听"); } } public void RemoveListener(Action ac) { if (changeList.Contains(ac)) { changeList.Remove(ac); } else { Debug.LogWarning("移除的消息不存在"); } } public void ClearListener() { changeList.Clear(); Debug.Log("清理成功"); } private void DispatchAll() { foreach (var item in changeList) { item(); } } } /// <summary> /// Dic /// 使用IReadOnlyDictionary作为保护 /// 通过Add RemoveByKey Update Clear 对数据进行操作 /// </summary> /// <typeparam name="T"></typeparam> public class BindableDic<T,V> { private List<Action> changeList = new List<Action>(); private Dictionary<T, V> _data; public IReadOnlyDictionary<T, V> data { get { return _data; } } public BindableDic() { _data = new Dictionary<T, V>(); } public void Add(T t, V v) { _data.Add(t,v); DispatchAll(); } public void RemoveByKey(T _key) { if (_data.ContainsKey(_key)) { _data.Remove(_key); DispatchAll(); } } public void Clear() { _data.Clear(); DispatchAll(); } public void Update(Dictionary<T,V> _dic) { _data = _dic; DispatchAll(); } public void AddListener(Action ac) { if (!changeList.Contains(ac)) { changeList.Add(ac); } else { Debug.LogWarning("重复监听"); } } public void RemoveListener(Action ac) { if (changeList.Contains(ac)) { changeList.Remove(ac); } else { Debug.LogWarning("移除的消息不存在"); } } public void ClearListener() { changeList.Clear(); Debug.Log("清理成功"); } private void DispatchAll() { foreach (var item in changeList) { item(); } } }
调用,在unity实现
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 数据自动变化 /// /// 方案对比: /// 表现层监听消息--->数据层改变发消息---->表现层收到消息,表现层改变 /// 表现层监听消息--->数据层改变会自动发消息(少写了发消息的代码),表现层改变 /// 优点:少写了发消息的代码 /// </summary> public class TestBind : MonoBehaviour { BindableProperty<int> hpData = new BindableProperty<int>(100); BindableList<int> friendList = new BindableList<int>(); BindableDic<int, string> myDic = new BindableDic<int, string>(); // Start is called before the first frame update void Start() { hpData.AddListener(delegate() { print("hh" + hpData.data); }); friendList.AddListener(delegate () { print("ff" + friendList.data.Count); }); myDic.AddListener(delegate () { print("dd" + myDic.data.Count); }); } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Q)) { hpData.data = 99; } if (Input.GetKeyDown(KeyCode.W)) { friendList.Add(658); friendList.Add(638); } if (Input.GetKeyDown(KeyCode.E)) { print(friendList.data.Count); } if (Input.GetKeyDown(KeyCode.R)) { myDic.Add(1,"sas"); myDic.Add(2, "sas2212"); print(myDic.data.Count); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~