将int[]传入dynamic参数方法时触发RunTimeBinderException的原因排查
为什么将参数改为dynamic后无法访问Count属性?
这事儿我太熟了,核心问题出在C#动态绑定的规则和**.NET数组对ICollection接口的显式实现**上,咱们掰开了说:
1. 用ICollection参数时为什么正常?
当参数类型是ICollection时,编译阶段就已经确定了array是ICollection接口类型,编译器直接帮你绑定到接口定义的Count属性——这是编译时绑定,完全没问题,不管传入的是数组还是其他ICollection实现类,都能正确访问接口的成员。
2. 改成dynamic后为什么抛异常?
当参数换成dynamic,C#会切换到运行时绑定:它不会在编译时检查成员,而是在运行时根据传入对象的实际类型(这里是int[],也就是.NET的数组类型)去查找公共实例成员。
但问题来了:.NET的数组是显式实现ICollection接口的Count属性的。显式接口实现的成员有个特点:它们不属于对象的公共实例成员,只能通过接口类型的引用来访问。你直接用int[]类型的变量去访问Count,运行时绑定器根本找不到这个成员——因为int[]的公共成员里只有Length,没有Count。
3. 怎么解决这个问题?
有两种靠谱的办法:
- 显式转换为ICollection:在访问Count前,把dynamic变量转成ICollection类型,强制绑定到接口成员:
private static int GetCount(dynamic array) { return ((ICollection)array).Count; } - 直接访问数组的Length属性:如果确定传入的都是数组,也可以直接用
array.Length,但这种方式通用性差,不如第一种稳妥。
内容的提问来源于stack exchange,提问作者rahulaga-msft
相关产品推荐
相关产品推荐

