🎯 泛型方法 OpenPanel<T>()

基础语法解释:

// 这是一个泛型方法,<T> 表示类型参数
public void OpenPanel<T>(PanelParamBase param = null) where T : UIBasePanel

简单理解:

  • <T> 就像一个占位符,代表"某种类型"
  • 调用时用具体类型替换T

实际例子对比:

// 传统写法(需要为每个Panel写一个方法)
public void OpenCommonTipPanel(CommonTipPanelParam param) { }
public void OpenLoginPanel(LoginPanelParam param) { }
public void OpenSettingPanel(SettingPanelParam param) { }

// 泛型写法(一个方法搞定所有Panel)
public void OpenPanel<T>(PanelParamBase param) { }

// 使用时:
OpenPanel<CommonTipPanel>(参数);  // T = CommonTipPanel
OpenPanel<LoginPanel>(参数);      // T = LoginPanel  
OpenPanel<SettingPanel>(参数);    // T = SettingPanel

好处: 避免重复代码,一个方法适用所有Panel类型!

🏗️ 对象初始化语法 new XXX() {}

传统写法 vs 简化写法:

// 传统写法(分步骤)
CommonTipPanelParam param = new CommonTipPanelParam();
param.Info = "点击确定进入XXX!";
param.PosType = CommonTipPanelParam.CommonTipPosType.Bottom;
_uiManager.OpenPanel<CommonTipPanel>(param);

// 简化写法(对象初始化器)
_uiManager.OpenPanel<CommonTipPanel>(new CommonTipPanelParam()
{
    Info = "点击确定进入XXX!",
    PosType = CommonTipPanelParam.CommonTipPosType.Bottom
});

理解:

  • new CommonTipPanelParam() - 创建新对象
  • { Info = "xxx", PosType = xxx } - 同时设置属性值
  • 相当于创建对象后立即赋值

🎭 Lambda表达式(委托的简化写法)

委托演进史:

// 1. 最原始写法(定义单独方法)
void OnViewLoaded(UIViewBase view)
{
    view.Name = uiName;
    loadingList.Remove(uiName);
    InitPanel(view, modelPanel, callBack);
}
m_PoolMgr.Spawn<UIViewBase>(poolType, uiName, OnViewLoaded);

// 2. 匿名方法
m_PoolMgr.Spawn<UIViewBase>(poolType, uiName, delegate(UIViewBase view)
{
    view.Name = uiName;
    loadingList.Remove(uiName);
    InitPanel(view, modelPanel, callBack);
});

// 3. Lambda表达式(最简洁)
m_PoolMgr.Spawn<UIViewBase>(poolType, uiName, (view) =>
{
    view.Name = uiName;
    loadingList.Remove(uiName);
    InitPanel(view, modelPanel, callBack);
});

Lambda语法解析:

(参数) => { 执行代码 }
//  ↑      ↑       ↑
// 输入   箭头   输出/操作

更多例子:

// 单个参数可以省略括号
view => { view.Name = "test"; }

// 单行代码可以省略大括号
x => x * 2

// 多个参数
(x, y) => x + y

// 无参数
() => Debug.Log("Hello");

🎮 按钮事件绑定的委托

Unity按钮事件的多种写法:

// 1. 指向已存在的方法
_view.OkBtn.onClick.AddListener(OnOkBtnClick);

// 2. Lambda表达式(推荐)
_view.CloseBtn.onClick.AddListener(() => {
    Close();
});

// 3. 带参数的Lambda
_view.DeleteBtn.onClick.AddListener(() => {
    DeleteItem(itemId);
});

// 4. 多行代码的Lambda
_view.ConfirmBtn.onClick.AddListener(() => {
    PlaySound();
    ShowEffect();
    Close();
});

🌟 实际开发中的常见模式

完整的Panel创建流程:

// 第1步:定义参数类
public class MyPanelParam : PanelParamBase
{
    public string Title;
    public int Score;
    public Action OnConfirm;  // 回调委托
}

// 第2步:调用打开Panel
_uiManager.OpenPanel<MyPanel>(new MyPanelParam()
{
    Title = "游戏结束",
    Score = 12345,
    OnConfirm = () => {
        // 确认后执行的代码
        RestartGame();
    }
});

// 第3步:Panel中使用参数
public override void Open(PanelParamBase param = null)
{
    if (param is MyPanelParam myParam)
    {
        _view.TitleText.text = myParam.Title;
        _view.ScoreText.text = myParam.Score.ToString();
        
        // 绑定按钮事件
        _view.ConfirmBtn.onClick.AddListener(() => {
            myParam.OnConfirm?.Invoke();  // 调用回调
            Close();
        });
    }
}

🎯 新手练习建议

从简单到复杂:

// 练习1:简单的Lambda
List<int> numbers = new List<int> {1, 2, 3, 4, 5};
var evenNumbers = numbers.Where(x => x % 2 == 0);  // 筛选偶数

// 练习2:按钮事件
button.onClick.AddListener(() => Debug.Log("点击了!"));

// 练习3:带参数的委托
Action<string> showMessage = (msg) => Debug.Log(msg);
showMessage("Hello World");

// 练习4:泛型方法
public T GetComponent<T>() where T : Component
{
    return GetComponent(typeof(T)) as T;
}

📝 记忆口诀

  • 泛型 = 类型占位符,让一个方法适用多种类型
  • 对象初始化 = 创建对象时直接设置属性,简化代码
  • Lambda = 匿名函数的简写,(参数) => { 代码 }
  • 委托 = 方法的指针,可以传递和调用

别担心,这些语法用多了就熟悉了!先理解概念,然后多练习~ 加油! 💪

更多推荐