请解释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或者直接调用。
如何简化这部分代码
有两种更简洁的写法,取决于你的使用场景:
用泛型版
CreateDelegate(推荐,.NET 3.5+支持)
.NET后来给MethodInfo加了泛型扩展方法CreateDelegate<T>,可以省去手动指定类型和强制转换的步骤,代码更清爽:var del = scriptFunc.CreateDelegate<Func<GameObject, MonoBehaviour>>(); MonoBehaviour addComponent = del(gameObj); // 这里甚至可以省略.Invoke,直接像函数一样调用直接反射调用(适合单次调用场景)
如果只是调用一次这个方法,完全没必要创建委托,直接用MethodInfo.Invoke就行:MonoBehaviour addComponent = (MonoBehaviour)scriptFunc.Invoke(null, new object[] { gameObj });这里第一个参数传
null,是因为推测AddScriptToComponent是静态方法(如果是实例方法,需要传入该类的实例对象)。
内容的提问来源于stack exchange,提问作者IMGSaibh




