为何无法将含低派生参数的Lambda赋值给逆变的Action<T>变量?
原因解析
核心在于编译器对lambda表达式的类型推断规则,以及逆变转换的触发逻辑:
直接赋值lambda时的类型推断限制
当你直接写c = (Animal a) => { };时,编译器需要先确定这个lambda的具体委托类型。虽然Action<Cat>是最终的目标类型,但编译器不会同时完成“推断lambda的委托类型”和“执行逆变转换”这两步操作——它不会自动把lambda的参数类型Animal逆变适配成Cat,因为此时lambda还没绑定到任何明确的委托类型上。中间变量的中转作用
先把lambda赋值给Action<Animal> b时,编译器已经明确这个lambda的类型是Action<Animal>。之后把b赋值给c(Action<Cat>),就只是单纯的委托类型逆变转换——这是C#明确支持的特性,因为Action<T>用in关键字标记了逆变,Action<Animal>可以安全转换为Action<Cat>(毕竟能处理Animal的方法,肯定能处理它的子类Cat)。额外说明
编译器对lambda的类型推断是基于目标类型的,但这个目标类型必须和lambda的参数/返回值类型直接匹配,不会自动触发协变或逆变转换。只有当lambda先被解析为一个具体的委托类型后,才能对该委托类型进行协变/逆变转换。
内容的提问来源于stack exchange,提问作者rory.ap
相关产品推荐
相关产品推荐

