You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

请解释Unity C#代码中委托语法及最后三行含义与简化方式

关于C#委托创建与代码简化的问题解答

嘿,我来帮你拆解这段Unity/C#代码里的疑惑点,一步步讲清楚:

最后三行代码的含义

咱们先把这几行的作用拆解开:

  • 委托创建行var del = (Func<GameObject, MonoBehaviour>) System.Delegate.CreateDelegate(typeof(Func<GameObject, MonoBehaviour>), scriptFunc);
    这行的核心是把通过反射拿到的MethodInfo(也就是scriptFunc指向的AddScriptToComponent方法),包装成一个强类型的委托实例。这样做的好处是,后续调用这个方法时不用再走反射的流程,性能更高,写法也更直观。
  • 委托调用行MonoBehaviour addComponent = del.Invoke(gameObj);
    这行就是执行刚才创建的委托,传入gameObj作为参数,本质就是调用AddScriptToComponent方法,最后把方法返回的MonoBehaviour对象赋值给变量。

详解Delegate.CreateDelegate这段语法

System.Delegate.CreateDelegate是.NET框架提供的一个反射工具方法,专门用来把MethodInfo对象转换成具体的委托类型,让动态获取的方法可以像普通委托一样调用。咱们拆解它的参数:

  • 第一个参数typeof(Func<GameObject, MonoBehaviour>):指定要创建的委托类型。这里Func<GameObject, MonoBehaviour>是.NET内置的泛型委托,代表“接收一个GameObject参数,返回MonoBehaviour类型值”的方法签名——这个签名必须和AddScriptToComponent方法完全匹配,否则会抛出异常。
  • 第二个参数scriptFunc:就是我们通过assembly.GetType(className).GetMethod(...)拿到的MethodInfo对象,代表要被包装的目标方法。
  • 外面的(Func<GameObject, MonoBehaviour>)是显式类型转换:因为CreateDelegate的返回值是Delegate基类,必须转成具体的泛型委托类型,才能用Invoke或者直接调用。

如何简化这部分代码

有两种更简洁的写法,取决于你的使用场景:

  1. 用泛型版CreateDelegate(推荐,.NET 3.5+支持)
    .NET后来给MethodInfo加了泛型扩展方法CreateDelegate<T>,可以省去手动指定类型和强制转换的步骤,代码更清爽:

    var del = scriptFunc.CreateDelegate<Func<GameObject, MonoBehaviour>>();
    MonoBehaviour addComponent = del(gameObj); // 这里甚至可以省略.Invoke,直接像函数一样调用
    
  2. 直接反射调用(适合单次调用场景)
    如果只是调用一次这个方法,完全没必要创建委托,直接用MethodInfo.Invoke就行:

    MonoBehaviour addComponent = (MonoBehaviour)scriptFunc.Invoke(null, new object[] { gameObj });
    

    这里第一个参数传null,是因为推测AddScriptToComponent是静态方法(如果是实例方法,需要传入该类的实例对象)。

内容的提问来源于stack exchange,提问作者IMGSaibh

火山引擎 最新活动