montaque

小碗喝酒,小口吃肉

博客园 首页 新随笔 联系 订阅 管理
  119 随笔 :: 1 文章 :: 686 评论 :: 29万 阅读

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


namespace XXXXXXX
{
    
public class A
    
{
        
private int Add(int a, int b)
        
{
            
return a + b;
        }

        
    }

}

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

VS 2005 自动生成的单元测试代码
       [DeploymentItem("XXXXXXX.exe")]
        [TestMethod()]
        
public void AddTest()
        
{
            A target 
= new A();

            TestProject1.XXXXXXX_AAccessor accessor 
= new TestProject1.XXXXXXX_AAccessor(target);

            
int a = 0// TODO: Initialize to an appropriate value

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

            
int expected = 0;
            
int actual;

            actual 
= accessor.Add(a, b);

            Assert.AreEqual(expected, actual, 
"XXXXXXX.A.Add did not return the expected value.");
            Assert.Inconclusive(
"Verify the correctness of this test method.");
        }

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

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

}

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

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

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

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

对于Private

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

为此他还列举了一个例子:
class A
{
    
int x;
    
static void F(B b) {
        b.x 
= 1;    // Ok,这里x事实上是private 的变量
    }

}

class B: A
{
    
static void F(B b) {
        b.x 
= 1;        // Error, x not accessible
    }

}


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


posted on   montaque  阅读(2270)  评论(2编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示