1

我有一个 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;
    }
}
4

7 回答 7

5

这个问题在这一点上有点老了,但这是另一种方法,按照你的要求做,没有讲座或摇摆手指:

考虑:

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

警告:使用上述代码会破坏封装,弯曲您的脊椎,并且可能会因 OO 纯粹主义者的尖锐尖叫而导致耳朵受损。

...但它适用于工厂类,弥补了 C# 缺少朋友关键字的问题。

警告 2:这很慢。

于 2013-12-23T16:06:05.987 回答
5

您可以使用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;
    }
}
于 2014-03-26T11:07:37.730 回答
3

您将需要为该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;
    }
}
于 2012-04-29T19:12:17.913 回答
3

你应该查看官方的 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 设置/调用内部方法/字段。

于 2012-04-29T19:49:47.190 回答
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;
          }
      }
   }
于 2012-04-29T19:13:31.037 回答
0

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

  • 从 A 继承
  • 创建一个设置 X 值的公共方法 setX(int newX)。
于 2012-04-29T19:11:53.550 回答
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;
    }
}
于 2012-04-29T19:23:19.670 回答