C#怎么使用协变和逆变 C#泛型中的in和out关键字协变逆变是什么意思怎么用【语法】

张开发
2026/4/10 4:04:17 15 分钟阅读

分享文章

C#怎么使用协变和逆变 C#泛型中的in和out关键字协变逆变是什么意思怎么用【语法】
协变out和逆变in仅适用于接口和委托协变允许更具体的类型赋给更宽泛的类型变量仅限返回值、get访问器等输出位置逆变则用于输入位置如方法参数仅限接口和委托类不支持协变或逆变。协变out只适用于接口和委托且只能用在输出位置协变允许你把更具体的类型赋给更宽泛的类型变量比如 IEnumerablestring 能赋给 IEnumerableobject。但这不是所有泛型都支持——只有标记了 out 的类型参数才允许协变而且它**只能出现在返回值、属性 get 访问器、方法返回类型中**不能出现在参数、字段或 set 访问器里。常见错误现象void Add(T item) 里用了 out T编译直接报错 CS1961“类型参数 T 具有无效的方差”。IEnumerableT、IComparerout T、Funcout T 是典型协变接口/委托自定义接口要协变必须显式写 interface IProducerout T且所有 T 出现位置都得是“只读”的类不支持协变或逆变——class Listout T 是非法语法逆变in只用于输入位置且仅限接口和委托逆变让你把更宽泛的类型传给更具体的期望比如 Actionobject 可以赋给 Actionstring因为 string 是 object 的子类而 Action 只消费参数不返回它。逆变的关键是类型参数只能出现在**参数位置**不能用于返回值或属性 get。使用场景当你需要一个“能处理任意父类的委托”但实际只想传子类实例时逆变就省去了手动包装。Actionin T、IComparerin T、Predicatein T 是典型逆变接口/委托错误写法T GetFirst() 出现在 interface IConsumerin T 里 → 编译失败 CS1961注意 IComparerT 同时支持 in 和 out不对。.NET 中它是 IComparerin T因为比较逻辑只接收两个 T 参数不返回 T泛型类永远不支持 in/out别试了你没法给 class BoxT 加 in 或 out。C# 语言规范明确禁止——类的类型参数必须是不变的invariant。这是因为类既有输入构造函数、方法参数又有输出属性、返回值无法统一满足协变或逆变约束。 Tellers AI Tellers是一款自动视频编辑工具可以将文本、文章或故事转换为视频。

更多文章