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

本文关键字:受保护 成员 另一个 访问 | 更新日期: 2023-09-27 18:32:32

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

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

可以使用 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;
    }
}
这个问题在

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

考虑:

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

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

。但它适用于工厂类,弥补了 C# 缺少 friend 关键字的不足。

警告 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;
    }
}

您应该查看官方 MSDN 朋友程序集。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 设置/调用内部方法/字段。

试试这个:

   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;
          }
      }
   }
如果从

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

  • 从 A 继承
  • 创建一个公共方法 setX(int newX) 来设置 X 的值。

其他替代方案:

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;
    }
}