协变(out)和逆变(in)仅适用于接口和委托,协变允许更具体的类型赋给更宽泛的类型变量,仅限返回值、get访问器等输出位置;逆变则用于输入位置如方法参数,仅限接口和委托;类不支持协变或逆变。协变(out)只适用于接口和委托,且只能用在输出位置协变允许你把更具体的类型赋给更宽泛的类型变量,比如 IEnumerable<string> 能赋给 IEnumerable<object>。但这不是所有泛型都支持------只有标记了 out 的类型参数才允许协变,而且它**只能出现在返回值、属性 get 访问器、方法返回类型中**,不能出现在参数、字段或 set 访问器里。常见错误现象:void Add(T item) 里用了 out T,编译直接报错 CS1961:"类型参数 T 具有无效的方差"。IEnumerable<T>、IComparer<out T>、Func<out T> 是典型协变接口/委托自定义接口要协变,必须显式写 interface IProducer<out T>,且所有 T 出现位置都得是"只读"的类不支持协变或逆变------class List<out T> 是非法语法逆变(in)只用于输入位置,且仅限接口和委托逆变让你把更宽泛的类型传给更具体的期望,比如 Action<object> 可以赋给 Action<string>(因为 string 是 object 的子类,而 Action 只消费参数,不返回它)。逆变的关键是:类型参数只能出现在**参数位置**,不能用于返回值或属性 get。使用场景:当你需要一个"能处理任意父类的委托",但实际只想传子类实例时,逆变就省去了手动包装。Action<in T>、IComparer<in T>、Predicate<in T> 是典型逆变接口/委托错误写法:T GetFirst() 出现在 interface IConsumer<in T> 里 → 编译失败 CS1961注意 IComparer<T> 同时支持 in 和 out?不对。.NET 中它是 IComparer<in T>,因为比较逻辑只接收两个 T 参数,不返回 T泛型类永远不支持 in/out,别试了你没法给 class Box<T> 加 in 或 out。C# 语言规范明确禁止------类的类型参数必须是不变的(invariant)。这是因为类既有输入(构造函数、方法参数),又有输出(属性、返回值),无法统一满足协变或逆变约束。 Tellers AI Tellers是一款自动视频编辑工具,可以将文本、文章或故事转换为视频。
相关推荐
为啥全要学9 分钟前
自注意力中随着根号dk的增大,qk点积的方差为什么也会增大来两个炸鸡腿41 分钟前
【Datawhale2607】llm-algo-leetcode task02 基础算子庵中十三居士1 小时前
【纯AI无人工修改】AI Agent从0到1实战:50行Python手写核心循环,一次看懂所有Agent框架的底层逻辑人工智能培训1 小时前
世界模型内嵌,感知交互跃迁隔壁阿布都1 小时前
ClickHouse完整指南TDengine (老段)1 小时前
TDengine JOIN 完整语法 — Inner/Outer/ASOF/Window 全语法详解ai_coder_ai1 小时前
编写自动化脚本,在自己后端服务中使用云原生Baas服务进行编码和解码相关操作天天爱吃肉82182 小时前
# 商用车多体动力学整车仿真学习笔记(开篇总览)Allen说改装2 小时前
2025 APAxpo佛山改装展的展出规模达到了多少平方米?