C#中的类访问

时间:2013-01-12 18:17:47

标签: c# c#-4.0

对于class A中的instanceOfClassAclass B)实例,C#(4+)中是否有办法访问变量x(如SomeMethodInClassA中所述) x是公开的(参见下面的代码示例)?

    class A
    {
    B linkToClassB;

    void SomeMethodInClassA()
    {
    linkToClassB.x = 1;
    }
    };

    class B
    {
    public int x; // This should be accessible from class A without being public

    A instanceOfClassA;
    ...
    };

我想知道因为instanceOfClassAclass B的成员,所以可能有一种方法允许类访问其成员类的特定方法。

6 个答案:

答案 0 :(得分:3)

A有两个选项可以访问x而不将类作为同一层次结构的一部分:

嵌套类

如果AB内的嵌套类,则A可以访问x

class B {
    private int X;
    A instanceOfClassA;

    private class A {
        B linkToClassB;
        void SomeMethodInClassA() { linkToClassB.x = 1; }
    }
}

internal访问

如果这两个类在同一个程序集中且xinternal,那么A可以访问它。当然,在这种情况下,也可以从同一个程序集中的所有其他类访问x,这可能是不可取的。

class A
{
    B linkToClassB;

    void SomeMethodInClassA() { linkToClassB.x = 1; }
}

class B
{
    internal int x;
    A instanceOfClassA;
}

答案 1 :(得分:2)

您可以将x声明为

internal int x;

只要AB在同一个程序集中就可以使用。 internal正是为这种情况提供的,而在C#中它是唯一的机制。

答案 2 :(得分:1)

如果您被允许访问其他类的私人成员,则EncapsulationOOP的目的将被销毁。

除非您使用private(需要公开)或Property

,否则您无法访问其他班级的Reflection成员

答案 3 :(得分:1)

您可以使用接口的显式实现公开该属性。这样,可以使用对接口的引用来访问该属性,但是使用对该类的引用无法访问该属性:

public class A {

  private AccessB linkToB;

  void SomeMethodInClassA() {
    linkToB.X = 1;
  }

}

public interface AccessB {

  int X { get; set; }

}

public class B : AccessB {

  private int x;

  int AccessB.X { get { return x; } set { x = value; } }

};

答案 4 :(得分:1)

internal关键字可以满足您的需求。它只允许从相同的程序集(想想 DLL EXE )进行访问。

但更重要的是,你应该想到为什么你想要这种类型的功能。最好的做法是避免耦合(两个类相互依赖)。是否可以在对象 A B 构造函数中传递某些内容以允许它们共享数据?可能是 A B 上具有public访问者的set媒体资源?

有些情况下internal是最佳选择,但就像螺丝刀可以用来锤钉子一样,它并不是最好的方法。如果其他选项都不可行,我建议你使用internal作为最后的手段。

为了让您了解internal关键字的优点,让我们从 C#中考虑平台调用( pInvoke )Win32函数:

[Flags]
internal enum ProcessAccessFlags : uint
{
  None = 0x0,
  VmOperation = 0x8,
  VmRead = 0x10,
  VmWrite = 0x20,
  QueryInformation = 0x400
}

internal static class NativeMethods
{
  [DllImport("kernel32")]
  internal static extern IntPtr OpenProcess(ProcessAccessFlags desiredAccess,
                                            bool inheritHandle,
                                            int processId);
  [DllImport("kernel32")]
  internal static extern bool ReadProcessMemory(IntPtr hProcess, 
                                                IntPtr baseAddress,
                                                byte[] buffer,
                                                int count, 
                                                out int numberOfBytesRead);

  [DllImport("kernel32")]
  internal static extern bool WriteProcessMemory(IntPtr hProcess, 
                                                 IntPtr baseAddress,
                                                 byte[] buffer,
                                                 int count, 
                                                 out int numberOfBytesWritten);

  [DllImport("kernel32")]
  internal static extern int ResumeThread(IntPtr hThread);

  [DllImport("kernel32")]
  internal static extern bool CloseHandle(IntPtr handle);
}

此处internal关键字非常有意义,因为我的库中的各种类可能需要访问NativeMethods.CloseHandle()等。但是,我不希望可能使用我的类库的人可以访问NativeMethods类,因为它严格用于底层实现细节。

答案 5 :(得分:0)

你可以使它internal,所以只有那个程序集/ DLL中的类可以访问它,包括A. 但是可能有更好的模式,取决于你想用它做什么。