为何DataGridView.DataSource无法访问类的internal属性,但可访问internal类?
嘿,这个现象其实完全符合.NET的访问权限规则,一点都不是编译器的“奇怪行为”,咱们一步步理清楚:
首先先看你的代码示例:
internal class clsCustomers { public int ID { get; set; } internal string Name { get; set; } internal int Age { get; set; } // ...其他属性 } // 窗体代码里 DataGridView.DataSource = objCustList.GetAllCustomers();
第一部分:为什么internal类能被作为DataSource?
你的clsCustomers是internal修饰的,这个访问修饰符的意思是该类只能在当前程序集内被访问。而你的WinForm窗体代码(调用DataGridView.DataSource的地方)显然和这个类在同一个程序集里,所以你的代码能正常拿到这个类的实例列表,把它传给DataGridView完全没问题——毕竟调用方有访问这个类的权限。
第二部分:为什么internal属性不会显示在DataGridView里?
这才是关键:DataGridView的数据源绑定逻辑,底层依赖的是.NET的TypeDescriptor或者反射机制,而这些机制在访问成员的时候,是从System.Windows.Forms程序集的视角来判断可见性的,不是你的程序集!
internal属性的访问权限是“仅限当前程序集可见”,System.Windows.Forms是微软的官方程序集,和你的项目程序集完全是两个独立的程序集,所以它没有权限访问你的internal属性——自然就无法把这些属性识别为可绑定的列,所以不会显示在DataGridView里。
而public属性的访问权限是“所有程序集可见”,不管是你的代码还是System.Windows.Forms的代码,都能正常访问到这些属性,所以DataGridView能把它们渲染成列。
如果你确实需要用internal属性绑定怎么办?
如果因为某些原因不想把属性改成public,其实可以通过自定义TypeDescriptor或者给属性添加[Browsable(true)]配合反射权限设置,但说实话,这种做法有点绕。对于WinForm数据绑定场景来说,最直接也最符合常规做法的,还是把需要绑定的属性改成public——毕竟数据绑定本来就是要把数据暴露给UI层,public属性是最合理的选择。
内容来源于stack exchange

