C#使用dynamic访问私有类出现运行时错误的解决办法
问题原因
当MyClass是Program的私有嵌套类时,List<MyClass>这个类型在Helper类的上下文里是不可访问的。将泛型参数T(实际为List<MyClass>)转换为dynamic后,C#运行时绑定器在Helper的权限范围内无法识别T的真实类型,只能将其当作object处理,因此会抛出“‘object’不包含‘Count’定义”的异常。
解决办法
以下几种方案可以在保持MyClass私有性的前提下解决该问题:
1. 使用非泛型公共接口传递参数
将CountMethod的参数改为非泛型的IEnumerable(所有List<T>都实现了这个公共接口),这样运行时绑定器能够识别目标对象的类型并正常访问Count属性:
namespace ConsoleApp { internal class Program { static void Main(string[] args) { var myList = new List<MyClass>() { new MyClass(), new MyClass() }; Helper.CountMethod(myList); } private class MyClass { } } public static class Helper { public static void CountMethod(IEnumerable target) { dynamic targetD = target; var count = targetD.Count; // 正常获取Count值 } } }
2. 在私有类所在的内部类中提供访问入口
在Program类内部添加一个方法,负责将List<MyClass>转换为dynamic后传递给Helper。由于Program可以访问MyClass,这里的dynamic能够正确识别List<MyClass>的类型:
namespace ConsoleApp { internal class Program { static void Main(string[] args) { var myList = new List<MyClass>() { new MyClass(), new MyClass() }; Helper.CountMethod(GetDynamicList(myList)); } private class MyClass { } // 内部方法提供可识别的dynamic对象 private static dynamic GetDynamicList(List<MyClass> list) { return list; } } public static class Helper { public static void CountMethod(dynamic target) { var count = target.Count; // 正常获取Count值 } } }
3. 利用反射获取属性值
如果必须保留泛型参数T,可以通过反射绕开运行时绑定器的权限限制,直接获取Count属性的值:
namespace ConsoleApp { internal class Program { static void Main(string[] args) { var myList = new List<MyClass>() { new MyClass(), new MyClass() }; Helper.CountMethod(myList); } private class MyClass { } } public static class Helper { public static void CountMethod<T>(T target) { var countProp = typeof(T).GetProperty("Count"); if (countProp != null) { int count = (int)countProp.GetValue(target); // 处理count值 } } } }
内容的提问来源于stack exchange,提问作者Alison
相关产品推荐
相关产品推荐

