可能有重复:
为什么C#不提供类似C++的“friend”关键字?
我希望在不将私有成员变量暴露给其他类的情况下,让Tester类可以访问类的私有成员变量。
在 C++ 中,我只需将Tester类声明为友元类即可,那么在C#中该如何实现?能否给出一个示例?
可能有重复:
为什么C#不提供类似C++的“friend”关键字?
我希望在不将私有成员变量暴露给其他类的情况下,让Tester类可以访问类的私有成员变量。
在 C++ 中,我只需将Tester类声明为友元类即可,那么在C#中该如何实现?能否给出一个示例?
“朋友”一词没有直接的等价物——最接近的是InternalsVisibleTo(它与“朋友”的相似程度不是很高)。我只在测试时使用过此特性,非常方便!
示例:应放置在AssemblyInfo.cs
中。
[assembly: InternalsVisibleTo("OtherAssembly")]
最接近的相当于创建一个嵌套类,它将能够访问外部类的私有成员。类似于这样:
class Outer
{
class Inner
{
// This class can access Outer's private members
}
}
或者如果您更喜欢将内部类放在另一个文件中:
Outer.cs
partial class Outer
{
}
Inner.cs
partial class Outer
{
class Inner
{
// This class can access Outer's private members
}
}
假设有一个常见的模式。 类工厂制造小部件。 工厂类需要操作内部,因为它是工厂。 两者都在同一个文件中实现,并且根据设计和愿望以及本质,这些紧密耦合的类 - 实际上,Widget只是工厂的一种输出类型。
在C++中,使工厂成为Widget类的友元。
在C#中,我们可以做什么? 唯一好的解决方案是发明一个接口,IWidget,只公开公共方法,并使工厂返回IWidget接口。
这涉及相当多的乏味工作-在接口中再次公开所有通常公开的属性。
C#中没有'friend'关键字,但是一个测试私有方法的选项是使用System.Reflection获取方法句柄。这将允许您调用私有方法。
假设有这样一个类定义:
public class Class1
{
private int CallMe()
{
return 1;
}
}
您可以使用以下代码调用它:
Class1 c = new Class1();
Type class1Type = c.GetType();
MethodInfo callMeMethod = class1Type.GetMethod("CallMe", BindingFlags.Instance | BindingFlags.NonPublic);
int result = (int)callMeMethod.Invoke(c, null);
Console.WriteLine(result);
如果您正在使用Visual Studio Team System,则可以通过右键单击方法并选择“创建单元测试…”来使VS自动在其中生成具有私有访问器的代理类。
如果拥有权限访问的类位于另一个包内并且你要公开的方法标记为 internal 或 internal protected,那么你可以模拟朋友访问。
你需要修改想要共享的程序集,并在 AssemblyInfo.cs 中添加以下设置:
// Expose the internal members to the types in the My.Tester assembly
[assembly: InternalsVisibleTo("My.Tester, PublicKey=" +
"012700000480000094000000060200000024000052534131000400000100010091ab9" +
"ba23e07d4fb7404041ec4d81193cfa9d661e0e24bd2c03182e0e7fc75b265a092a3f8" +
"52c672895e55b95611684ea090e787497b0d11b902b1eccd9bc9ea3c9a56740ecda8e" +
"961c93c3960136eefcdf106955a4eb8fff2a97f66049cd0228854b24709c0c945b499" +
"413d29a2801a39d4c4c30bab653ebc8bf604f5840c88")]