Private 访问控制符的准确意义

博客介绍了类成员可访问域的相关内容,成员可分为顶级和嵌套的,程序和类型都有各自的程序文本定义,还提到若成员已声明可访问性为 private,其可访问域是对应类型的程序文本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设我写了一个类,代码如下

None.gif
None.gif
namespace XXXXXXX
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
public class A
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private int Add(int a, int b)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return a + b;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

如果要单元测试A的Add 方法的话, 由于Add 是private 的, 单元测试代码无法直接访问,这时候,我们可以利用反射来作. 微软很多的bug也多数通过反射,访问private 属性或者字段可以fix

VS 2005 自动生成的单元测试代码
None.gif       [DeploymentItem("XXXXXXX.exe")]
None.gif        [TestMethod()]
None.gif        
public void AddTest()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif{
InBlock.gif            A target 
= new A();
InBlock.gif
InBlock.gif            TestProject1.XXXXXXX_AAccessor accessor 
= new TestProject1.XXXXXXX_AAccessor(target);
InBlock.gif
InBlock.gif            
int a = 0// TODO: Initialize to an appropriate value
InBlock.gif

InBlock.gif            
int b = 0// TODO: Initialize to an appropriate value
InBlock.gif

InBlock.gif            
int expected = 0;
InBlock.gif            
int actual;
InBlock.gif
InBlock.gif            actual 
= accessor.Add(a, b);
InBlock.gif
InBlock.gif            Assert.AreEqual(expected, actual, 
"XXXXXXX.A.Add did not return the expected value.");
InBlock.gif            Assert.Inconclusive(
"Verify the correctness of this test method.");
ExpandedBlockEnd.gif        }

而这里的XXXXXXX_AAccessor就是一个wrapper 来通过反射调用对象的方法,代码如下
None.gif[System.Diagnostics.DebuggerStepThrough()]
None.gif[System.CodeDom.Compiler.GeneratedCodeAttribute(
"Microsoft.VisualStudio.TestTools.UnitTestGeneration""1.0.0.0")]
ExpandedBlockStart.gifContractedBlock.gif
internal class XXXXXXX_AAccessor : BaseAccessor dot.gif{
InBlock.gif    
InBlock.gif    
protected static Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType m_privateType = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType(typeof(global::XXXXXXX.A));
InBlock.gif    
InBlock.gif    
internal XXXXXXX_AAccessor(global::XXXXXXX.A target) : 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
base(target, m_privateType) dot.gif{
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
internal int Add(int a, int b) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
object[] args = new object[] dot.gif{
InBlock.gif                a,
ExpandedSubBlockEnd.gif                b}
;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
int ret = ((int)(m_privateObject.Invoke("Add"new System.Type[] dot.gif{
InBlock.gif                    
typeof(int),
ExpandedSubBlockEnd.gif                    
typeof(int)}
, args)));
InBlock.gif        
return ret;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

这时候,有些人可能又疑惑,为啥private 的东西最终还是可以调用,起到封装的目的了吗?

..................... 

问题2: private 的到底是什么意思,我特意浏览了一下C#语言规范.

一个成员的可访问域由可能是不连续的程序文本节组成从那里可以访问该成员。出于定义成员可访问域的目的,如果成员不是在某个类型内声明的,就称该成员是顶级的;如果成员是在其他类型内声明的,就称该成员是嵌套的。此外,程序的程序文本定义为包含在该程序的所有源文件中的全部程序文本,而类型的程序文本定义为包含在该类型(可能还包括嵌套在该类型内的类型)的“类体”、“结构体”、“接口体”或“枚举体”中的开始和结束(“{”和“}”)标记之间的全部程序文本。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

对于Private

·         如果 M 的已声明可访问性为 private M 的可访问域是 T 的程序文本。

为此他还列举了一个例子:
None.gifclass A
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
int x;
ExpandedSubBlockStart.gifContractedSubBlock.gif    
static void F(B b) dot.gif{
InBlock.gif        b.x 
= 1;    // Ok,这里x事实上是private 的变量
ExpandedSubBlockEnd.gif
    }

ExpandedBlockEnd.gif}

None.gif
class B: A
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
static void F(B b) dot.gif{
InBlock.gif        b.x 
= 1;        // Error, x not accessible
ExpandedSubBlockEnd.gif
    }

ExpandedBlockEnd.gif}

None.gif

那反射呢? 反射可以不遵守嘛?呵呵,一会儿给出个完整的解释.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值