如何使用非dynamic集合存储泛型基类子类并调用其方法
解决方案:使用非泛型接口统一集合类型
要避免依赖dynamic,核心是给所有Pair<A,B>及其子类定义一个非泛型的公共契约,让它们都实现这个契约,这样集合就可以用契约类型来存储,编译时就能确保方法可调用。
具体实现步骤
1. 定义非泛型接口
创建一个包含ValueOneString()方法的非泛型接口,作为所有Pair类的公共抽象:
public interface IPair { string ValueOneString(); }
2. 修改泛型基类实现接口
让泛型Pair<A,B>实现这个接口(子类会自动继承接口实现,无需额外修改):
public class Pair<A, B> : IPair { protected readonly A value1; protected readonly B value2; public Pair(A value1, B value2) { this.value1 = value1; this.value2 = value2; } public string ValueOneString() { return value1.ToString(); } }
3. 使用接口类型的集合
将原来的List<dynamic>替换为List<IPair>,直接通过接口调用方法,编译时就能检查类型正确性:
public class Program { public static int Main(string[] args) { var pair = new Pair<int, int>(76, 4); var auPair = new AuPair("Mart", 25); var rePair = new RePair(false, 2.371); // 改用IPair类型的集合 var pairs = new List<IPair> { pair, auPair, rePair }; foreach (var p in pairs) { Console.WriteLine(p.ValueOneString()); } return 0; } }
为什么这比dynamic更好
- 编译时类型安全:如果某个类没有正确实现
ValueOneString(),编译阶段就会报错,而dynamic要到运行时才会发现问题。 - 性能更优:
dynamic依赖运行时类型解析,会带来额外开销,接口调用是直接的编译绑定,性能更高。 - 代码可读性更强:明确的接口类型能让其他开发者一眼看出集合中元素的公共行为,比模糊的
dynamic更清晰。
内容的提问来源于stack exchange,提问作者Isaac Thompson
相关产品推荐
相关产品推荐

