假設我寫了一個類,代碼如下
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
}
}

那反射呢? 反射可以不遵守嘛?呵呵,一會兒給出個完整的解釋.