Friend Class Equivalent in C#

Abdul Mateen Oct 12, 2023
  1. Friend Class in C++
  2. Use C# Equivalent of Friend Class
Friend Class Equivalent in C#

This tutorial will teach you about friend class equivalents in C#. First, we will discuss friend class and its usage in programming with C++ examples.

Next, in the absence of a friend class equivalent in C#, we’ll see the alternatives.

Friend Class in C++

An important programming feature mainly applied in object-oriented programming is data hiding. Keeping data members hidden from outside the class means that the data members can be updated within the class only.

Therefore, we can say that only one class (holding data members) can change the value of data members.

By hiding data, we reduce the testing scope because we must test the class we are modifying. No other class can access the private data members of some class; therefore, there is no need to test them if their code is not modified.

Sometimes, data hiding gets a little compromised in lengthy and complex codes. A class can declare some functions or classes as friends.

In response, the friend functions and friend classes can access the private data members.

The syntax of friendship is below.

class ABC {
  ... friend class XYZ;
  friend int change_data_member(int, char);
  ...

Class ABC declares class XYZ as a friend in line#3. Line#4 shows the syntax for declaring a friend method.

Here, class ABC declares the change_data_member method as a friend function.

After receiving the friendship flag from class ABC, every function of class XYZ can access the private data members of class ABC.

However, in case of granting friendship to a function has a limited scope of friendship. Only the friend function (i.e., declared as a friend) can access the private data of members of the friendship-granting class.

Let’s see the implementation of the friendship concept in C++.

#include <iostream>
using namespace std;
class ABC {
  int privateMember;

 public:
  ABC(int privateMember) { this->privateMember = privateMember; }
  friend int getPrivateMember(ABC &);
  friend void setPrivateMember(ABC &, int);
};
int getPrivateMember(ABC &obj) { return obj.privateMember; }
void setPrivateMember(ABC &obj, int privateMember) {
  obj.privateMember = privateMember;
}
int main() {
  ABC abc(5);
  cout << "Private Member: " << getPrivateMember(abc) << '\n';
  setPrivateMember(abc, 7);
  cout << "Private Member: " << getPrivateMember(abc) << '\n';
  return 0;
}

In this code, class ABC has private data member privateMember. In the last two lines of the class body, friendship is granted to two non-class functions: getPrivateMember and setPrivateMember.

The output of this code is below.

Private Member: 5
Private Member: 7

The private data member is accessed for both input and output. Following is an example of a friend class:

#include <iostream>
using namespace std;
class ABC {
  int privateMember;
  friend class DEF;
};
class DEF {
  ABC abc;

 public:
  int getPrivateMember() { return abc.privateMember; }
  void setPrivateMember(int privateMember) {
    abc.privateMember = privateMember;
  }
};
int main() {
  DEF def;
  def.setPrivateMember(12);
  cout << "Private Member: " << def.getPrivateMember() << '\n';
  return 0;
}

In the second line of class ABC, friendship is granted to class DEF. Having friendship status, the getPrivateMember and the setPrivateMember methods of the class DEF can access the private members of class ABC.

The output of this code is below.

Private Member: 12

This friend function or friend class concept is available in C++, not C#. However, there are some methods through which we can access non-member data functions.

Use C# Equivalent of Friend Class

There are different methods to access data members of any class from some non-member functions in C#. Let’s discuss this one by one.

Using Nested Classes

The closest C# equivalent/alternative of a C++ friend class is creating a nested/inner class. A nested class can access the private data members of an outer class.

The following example creates the Inner_class class as a nested class to Outer_class. Being inside the scope of a containing class, the Inner_class can access private members of the Outer_class, thereby imitating the friend class.

using System;
public class Outer_class {
  int privateMember;
  Outer_class(int privateMember) {
    this.privateMember = privateMember;
  }
  public class Inner_class {
    public void innerClassFunction() {
      Outer_class obj = new Outer_class(5);
      Console.WriteLine("Private Member: " + obj.privateMember);
    }
  }
}
public class Driver {
  static public void Main() {
    Outer_class.Inner_class obj = new Outer_class.Inner_class();
    obj.innerClassFunction();
  }
}

In the above code, we have one outer class and one inner class. The variable privateMember is a private member of the outer class.

Inside the Inner_class, we are accessing the private data member that is privateMember of the outer class.

Next, we have the Driver class, where we have created an object of the Inner_class. Using the Inner_class object, we call the innerClassFunction inside the Inner_class.

Output:

Private Member: 5

Though the above code builds and executes without issues, still, it is preferred to put the Inner_class separate from the Outer_class by using the partial class concept as given in the below example.

using System;
public partial class Outer_class {
  int privateMember;
  Outer_class(int privateMember) {
    this.privateMember = privateMember;
  }
}
public partial class Outer_class {
  public class Inner_class {
    public void innerClassFunction() {
      Outer_class obj = new Outer_class(5);
      Console.WriteLine("Private Member: " + obj.privateMember);
    }
  }
}
public class Driver {
  static public void Main() {
    Outer_class.Inner_class obj = new Outer_class.Inner_class();
    obj.innerClassFunction();
  }
}

In the second partial class definition of Outer_class, we have a function innerClassFunction. This innerClassFunction method creates an object of the outer class.

We pass 5 as an argument for the constructor parameter while creating an Outer_class object. This constructor parameter becomes the value of the data member in the first partial definition of the outer class, as seen in the output below.

Private Member: 5

Partial classes are important in large projects where multiple persons write different portions of a class.

Here, we are exploiting this partial class option and writing Inner_class inside as another partial portion of the outer class. This partial scheme can keep the partial units separate, yet we can use those as a single unit.

The main advantage of this scheme is that the actual class definition is not exposed to the one who writes the Inner_class definition.

Reflection Objects

Using the objects of Reflection, we can get run-time type information.

We can use Reflection objects to get the Type information during the program execution. The System.Reflection namespace can be used to access the metadata of a program in execution.

The System.Reflection provides useful information at run-time and helps add different types, values, and class objects to the program.

Moreover, we can get a handle on the methods using the System.Reflection namespace and test the class’s private methods.

In this way, we can invoke private methods of the class. Therefore, it can replicate the friend class.

For example, assume the following class with a private method callable_fun().

public class Class1 {
  private char callable_fun() {
    return 'C';
  }
}

To test the private function callable_fun, we need to write the following code:

using System.Reflection;
public class Driver {
  static public void Main() {
    Class1 c = new Class1();
    Type class1Type = c.GetType();
    MethodInfo callMeMethod =
        class1Type.GetMethod("callable_fun", BindingFlags.Instance | BindingFlags.NonPublic);
    char result = (char)callMeMethod.Invoke(c, null);
    Console.WriteLine("Output:" + result);
  }
}

The output of this code is below.

Output:C

If you are using the Visual Studio Team System, in that case, you can get VS to automatically generate a proxy class with private accessors by right-clicking the method and selecting Create Unit Tests....

Using the InternalsVisibleToAttribute Class

This class helps to enhance visibility to a specified assembly for those types usually visible within the current assembly only.

// Syntax
[System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public sealed class InternalsVisibleToAttribute : Attribute

If we have two unsigned assemblies, then the InternalsVisibleToAttribute class helps to access the private member of one unsigned assembly by another unsigned assembly. The name of one assembly (having the name of the friend class/assembly) is passed as an argument.

Next, let’s look at an example where InternalsVisibleToAttribute is used to access the private member of another unsigned assembly. Here, SecondClass accesses the private member of FirstClass.

See the below code.

using System;
using System.Runtime.CompilerServices;
using Utilities.Example;

[assembly:InternalsVisibleToAttribute("FirstClass")]

namespace Utilities.Example {
  public class FirstClass {
    internal static int InnerMethod(int x) {
      return x * x;
    }
  }
}

The following example provides the source code for the SecondClass assembly:

public class SecondClass {
  public static void Main() {
    Console.WriteLine(FirstClass.InnerMethod(10));
  }
}

The output of this code is 100.

If we have signed assemblies, then directory path and file name extension are not required.

The next example uses the InternalsVisibleToAttribute to call the private method named innerMethod in a signed assembly visible to another signed assembly. It defines the FirstClass class that includes an internal innerMethod method.

using System;
using System.IO;
using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo(
    "Friend_Assembly, PublicKey=002400000480000094" + "0000000602000000240000525341310004000" +
    "001000100bf8c25fcd44838d87e245ab35bf7" + "3ba2615707feea295709559b3de903fb95a93" +
    "3d2729967c3184a97d7b84c7547cd87e435b5" + "6bdf8621bcb62b59c00c88bd83aa62c4fcdd4" +
    "712da72eec2533dc00f8529c3a0bbb4103282" + "f0d894d5f34e9f0103c473dce9f4b457a5dee" +
    "fd8f920d8681ed6dfcb0a81e96bd9b176525a" + "26e0b3")]

public class FirstClass {
  internal static int innerMethod(int x) {
    return x * x;
  }
}

Suppose the following example is compiled into a strong-named assembly named Friend_Assembly. The inner method in FirstClass will successfully call the innerMethod, although the method is internal to the FirstClass.

public class SecondClass {
  public static void Main() {
    int result = FirstClass.innerMethod(10);
    Console.WriteLine(result);
  }
}

The output of this code is, again, 100.

We have presented different equivalents of the C++ friend class in C#. Readers can use any as per their requirements.

Related Article - Csharp Class