ares_games
ares_games

Reputation: 1067

Class access in C#

Is there a way in C# (4+) for the instance of class A (instanceOfClassA) in class B to access the variable x (as in SomeMethodInClassA) without x being public (see code example below)?

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

I was wondering that because as instanceOfClassA is a member of of class B there might be a way to allow a class to access pecific methods of their member classes.

Upvotes: 1

Views: 125

Answers (6)

Erik
Erik

Reputation: 12858

The internal keyword will do what you want. It only allows access from within the same assembly (think DLL or EXE).

More importantly however, you should think of why you want this type of functionality. It is best practice to avoid coupling (two classes relying on each other). Can something be passed in the constructor of object A or B that would allow them to share data? Perhaps a public property with a set accessor on either A or B?

There are cases where internal is the best choice, but just as a screwdriver can be used to hammer nails, it doesn't make it the best approach for everything. I would advise you use internal as a last resort if every other option just is not viable.

To give you an idea of what the internal keyword is great for, let's consider platform invoking (pInvoke) Win32 functions from within C#:

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

Here the internal keyword makes a lot of sense because various classes in my library may need access to NativeMethods.CloseHandle() or the like. However, I don't want people who may use my class library to have access to the NativeMethods class since it is strictly for under-the-hood implementation details.

Upvotes: 1

Guffa
Guffa

Reputation: 700222

You can expose the property using an explicit implementation of an interface. That way the property is reachable using a reference to the interface, but it's not reachable using a reference to the class:

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

};

Upvotes: 1

Rhumborl
Rhumborl

Reputation: 16609

You could make it internal, so only classes in that assembly/DLL can access it, including A. But there may be a better pattern, depending what you want to do with it.

Upvotes: 0

Henk Holterman
Henk Holterman

Reputation: 273179

You can declare x as

internal int x;

and as long as A and B are in the same assembly it will work. internal is provided precisely for this kind of situation and in C# it's the only mechanism.

Upvotes: 2

Jon
Jon

Reputation: 437336

There are two options for A being able to access x without the classes being part of the same hierarchy:

Nested class

If A is a nested class inside B then A can access x:

class B {
    private int X;
    A instanceOfClassA;

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

internal access

If the two classes are in the same assembly and x is be internal then it is possible for A to access it. Of course in this case it is possible to access x from all other classes in the same assembly as well, which might not be desirable.

class A
{
    B linkToClassB;

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

class B
{
    internal int x;
    A instanceOfClassA;
}

Upvotes: 3

Anirudha
Anirudha

Reputation: 32787

If you were allowed to access private members of other class,the very purpose of Encapsulation in OOP would be destroyed..

You cant access private members of other class unless you use Property(which needs to be public) or Reflection

Upvotes: 1

Related Questions