泛型协变致IBirdProcessor编译错误,类型转换失败该如何解决?
泛型鸟类处理器工厂的协变/逆变问题
定义的代码
鸟类接口与实现
public interface IBird { } public class Duck : IBird { public string DuckyProperty { get; set; } // 这是Duck特有的属性! }
鸟类处理器接口与实现
public interface IBirdProcessor<out T> where T : IBird { double GetBirdWeight(T obj); // 此处编译报错 } public class DuckProcessor : IBirdProcessor<Duck> { public double GetBirdWeight(Duck duck) { return double.Parse(duck.DuckyProperty); } }
鸟类处理器工厂
public class BirdProcessorFactory { public IBirdProcessor<T> GetBirdProcessor<T>(T obj) where T : IBird { return (IBirdProcessor<T>)new DuckProcessor(); } }
启动代码
static void Main() { var bird = new Duck() { DuckyProperty = "23" } as IBird; // 强制转换是为了模拟真实场景 var factory = new BirdProcessorFactory(); var provider = factory.GetBirdProcessor(bird); var weight = provider.GetBirdWeight(bird); }
遇到的问题
- 给
IBirdProcessor<T>添加out协变关键字时,编译报错:
The type parameter 'T' must be contravariantly valid on 'Program.IBirdProcessor<T>.GetBirdWeight(T)'. 'T' is covariant
翻译:类型参数
T在Program.IBirdProcessor<T>.GetBirdWeight(T)上必须是逆变有效的,而当前T被声明为协变。
- 移除
out关键字后,运行时抛出类型转换异常:
System.InvalidCastException: 'Unable to cast object of type 'DuckProcessor' to type 'IBirdProcessor`1[NotVegetables.Program+IBird]'.'
翻译:无法将类型为
DuckProcessor的对象强制转换为IBirdProcessor<IBird>类型。
临时解决方案(违背泛型初衷)
public class DuckProcessor : IBirdProcessor<IBird> { public double GetBirdWeight(IBird bird) { var duck = bird as Duck; return double.Parse(duck.DuckyProperty); } }
这个方案让DuckProcessor处理抽象的IBird而非仅处理Duck,完全违背了泛型的设计意图。
核心疑问
我的思路是不是完全错了?应该如何正确实现一个仅处理对应鸟类的泛型处理器工厂?
内容的提问来源于stack exchange,提问作者Nick Farsi
相关产品推荐
相关产品推荐

