访问另一个类的受保护成员

时间:2012-04-29 19:09:33

标签: c# class friend access-modifiers

我有一个A类,我需要从中访问类B的受保护成员,就像在C ++中使用friend关键字一样。但是,内部修饰符不适合我的需要。 B类需要创建一个A类实例,修改其私有数据,并返回对该类的引用。那些A类成员需要保持对原始呼叫者的私密性。

public class A
{
    protected int x;
}

public class B
{
    public static A CreateClassA()
    {
        A x = new A();
        x.x = 5;   // ERROR : No privilege
        return x;
    }
}

7 个答案:

答案 0 :(得分:4)

这个问题有点陈旧,但这是另一种方法,按照你的要求做,没有讲课或手指摇摆:

考虑:

A foo = new A();
FieldInfo privateField = foo.GetType().GetField("x", BindingFlags.NonPublic | BindingFlags.Instance);
privateField.SetValue(foo, 5);

警告:使用上述代码可打破封装,弯曲你的脊椎,并可能因OO纯粹主义者的尖叫而引起耳朵伤害。

...但它适用于工厂类,可以补偿C#缺少朋友关键字。

警告2:这很慢。

答案 1 :(得分:4)

您可以使用protected internal代替internal来访问同一程序集中的所有类,以及其他程序集中的子类:

public class A
{
    protected internal int x;
}

public class B
{
    public static A CreateClassA()
    {
        A x = new A();
        x.x = 5;   // hurray
        return x;
    }
}

答案 2 :(得分:2)

您需要为protected字段创建公共设置器或从类继承。

public class A
{
    protected int x;

    public int X { set { x = value; }  }
}

public static A CreateClassA()
{
    A x = new A();
    x.X = 5;
    return x;
}

或者:

public class B : A
{
    public static A CreateClassA()
    {
        this.x = 5; 
        return x;
    }
}

答案 3 :(得分:2)

您应该查看官方的MSDN Friend Assembly。 http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx 通过这个例子你可以做到:

using System.Runtime.CompilerServices;
using System;

[assembly: InternalsVisibleTo("AssemblyB")]
public sealed class A
{
    internal int x;
}

从程序集B设置/调用内部方法/字段。

答案 4 :(得分:1)

试试这个:

   public class A
   {
      protected int x;

      public class B
      {
          public static A CreateClassA()
          {
              A x = new A();
              x.x = 5;   // ERROR : No privilege
              return x;
          }
      }
   }

答案 5 :(得分:0)

如果您从A继承,则只能访问受保护的成员。您现在可以:

  • 继承自A
  • 创建一个公共方法setX(int newX),用于设置X的值。

答案 6 :(得分:0)

其他选择:

public class A
{
    public A() { }

    public A(int x)
    {
        this.x = x;
    }

    protected int x;
}

public class B
{
    public static A CreateClassA()
    {
        A x = new A(5);
        return x;
    }
}