代码之家  ›  专栏  ›  技术社区  ›  Ben L

C等同于朋友是什么?[复制品]

c#
  •  172
  • Ben L  · 技术社区  · 16 年前

    可能重复:
    Why does C# not provide the C++ style ‘friend’ keyword?

    我希望一个类的私有成员变量可以被一个测试类访问,而不将它们暴露在其他类中。

    在C++中,我只是把测试器类声明为一个朋友,如何在C语言中这样做呢?有人能给我举个例子吗?

    5 回复  |  直到 8 年前
        1
  •  241
  •   bytecode77    8 年前

    没有直接等同于“朋友”的东西——最接近的就是 InternalsVisibleTo . 我只在测试中使用过这个属性——它非常方便!

    例子: 被置于 AssemblyInfo.cs

    [assembly: InternalsVisibleTo("OtherAssembly")]
    
        2
  •  68
  •   Taryn Frank Pearson    13 年前

    壁橱等价物是创建一个嵌套类,该类将能够访问外部类的私有成员。像这样:

    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
        }
    }
    
        3
  •  40
  •   Freddy mac    14 年前

    采取一种非常常见的模式。类工厂生成小部件。工厂类需要处理内部结构,因为它是工厂。两者都是在同一个文件中实现的,并且根据设计、需求和本质,它们都是紧密耦合的类——事实上,小部件实际上只是工厂的一种输出类型。

    在C++中,使工厂成为WIDGET类的朋友。

    在C中,我们能做什么?我遇到的唯一体面的解决方案是发明一个接口Iwidget,它只公开公共方法,并让工厂返回Iwidget接口。

    这需要相当多的单调——在界面中再次暴露所有自然公共属性。

        4
  •  13
  •   RobG    16 年前

    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团队系统,那么您可以让vs通过右键单击该方法并选择“创建单元测试…”来自动生成包含私有访问器的代理类。

        5
  •  6
  •   tomfanning    12 年前

    如果授予访问权限的类位于另一个包中,并且要公开的方法标记为“内部”或“内部受保护”,则可以模拟友元访问。您必须修改要共享的程序集,并将以下设置添加到assemblyinfo.cs:

    // Expose the internal members to the types in the My.Tester assembly
    [assembly: InternalsVisibleTo("My.Tester, PublicKey=" +
    "012700000480000094000000060200000024000052534131000400000100010091ab9" +
    "ba23e07d4fb7404041ec4d81193cfa9d661e0e24bd2c03182e0e7fc75b265a092a3f8" +
    "52c672895e55b95611684ea090e787497b0d11b902b1eccd9bc9ea3c9a56740ecda8e" +
    "961c93c3960136eefcdf106955a4eb8fff2a97f66049cd0228854b24709c0c945b499" +
    "413d29a2801a39d4c4c30bab653ebc8bf604f5840c88")]
    

    根据需要,公钥是可选的。