Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does C# not provide the C++ style 'friend' keyword? [closed]

People also ask

Why is %d used in C?

In C programming language, %d and %i are format specifiers as where %d specifies the type of variable as decimal and %i specifies the type as integer. In usage terms, there is no difference in printf() function output while printing a number using %d or %i but using scanf the difference occurs.

Why semicolon is used in C?

Semicolons are end statements in C. The Semicolon tells that the current statement has been terminated and other statements following are new statements. Usage of Semicolon in C will remove ambiguity and confusion while looking at the code.

Why do we write in C?

It was mainly developed as a system programming language to write an operating system. The main features of the C language include low-level memory access, a simple set of keywords, and a clean style, these features make C language suitable for system programmings like an operating system or compiler development.

Why do people still use C instead of C++?

The biggest practical reason for preferring C is that support is more widespread than C++. There are many platforms, particularly embedded ones, that do not even have C++ compilers. There is also the matter of compatibility for vendors.


On a side note. Using friend is not about violating the encapsulation, but on the contrary it's about enforcing it. Like accessors+mutators, operators overloading, public inheritance, downcasting, etc., it's often misused, but it does not mean the keyword has no, or worse, a bad purpose.

See Konrad Rudolph's message in the other thread, or if you prefer see the relevant entry in the C++ FAQ.


Having friends in programming is more-or-less considered "dirty" and easy to abuse. It breaks the relationships between classes and undermines some fundamental attributes of an OO language.

That being said, it is a nice feature and I've used it plenty of times myself in C++; and would like to use it in C# too. But I bet because of C#'s "pure" OOness (compared to C++'s pseudo OOness) MS decided that because Java has no friend keyword C# shouldn't either (just kidding ;))

On a serious note: internal is not as good as friend but it does get the job done. Remember that it is rare that you will be distributing your code to 3rd party developers not through a DLL; so as long as you and your team know about the internal classes and their use you should be fine.

EDIT Let me clarify how the friend keyword undermines OOP.

Private and protected variables and methods are perhaps one of the most important part of OOP. The idea that objects can hold data or logic that only they can use allows you to write your implementation of functionality independent of your environment - and that your environment cannot alter state information that it is not suited to handle. By using friend you are coupling two classes' implementations together - which is much worse then if you just coupled their interface.


For info, another related-but-not-quite-the-same thing in .NET is [InternalsVisibleTo], which lets an assembly designate another assembly (such as a unit test assembly) that (effectively) has "internal" access to types/members in the original assembly.


You should be able to accomplish the same sorts of things that "friend" is used for in C++ by using interfaces in C#. It requires you to explicitly define which members are being passed between the two classes, which is extra work but may also make the code easier to understand.

If somebody has an example of a reasonable use of "friend" that cannot be simulated using interfaces, please share it! I'd like to better understand the differences between C++ and C#.


With friend a C++ designer has precise control over whom the private* members are exposed to. But, he's forced to expose every one of the private members.

With internal a C# designer has precise control over the set of private members he’s exposing. Obviously, he can expose just a single private member. But, it will get exposed to all classes in the assembly.

Typically, a designer desires to expose only a few private methods to selected few other classes. For example, in a class factory pattern it may be desired that class C1 is instantiated only by class factory CF1. Therefore class C1 may have a protected constructor and a friend class factory CF1.

As you can see, we have 2 dimensions along which encapsulation can be breached. friend breaches it along one dimension, internal does it along the other. Which one is a worse breach in the encapsulation concept? Hard to say. But it would be nice to have both friend and internal available. Furthermore, a good addition to these two would be the 3rd type of keyword, which would be used on member-by-member basis (like internal) and specifies the target class (like friend).

* For brevity I will use "private" instead of "private and/or protected".

- Nick


In fact, C# gives possibility to get same behavior in pure OOP way without special words - it's private interfaces.

As far as question What is the C# equivalent of friend? was marked as duplicate to this article and no one there propose really good realization - I will show answer on both question here.

Main idea was taking from here: What is a private interface?

Let's say, we need some class which could manage instances of another classes and call some special methods on them. We don't want to give possibility to call this methods to any other classes. This is exactly same thing what friend c++ keyword do in c++ world.

I think good example in real practice could be Full State Machine pattern where some controller update current state object and switch to another state object when necessary.

You could:

  • The easiest and worst way to make Update() method public - hope everyone understand why it's bad.
  • Next way is to mark it as internal. It's good enough if you put your classes to another assembly but even then each class in that assembly could call each internal method.
  • Use private/protected interface - and I followed this way.

Controller.cs

public class Controller
{
    private interface IState
    {
        void Update();
    }

    public class StateBase : IState
    {
        void IState.Update() {  }
    }

    public Controller()
    {
        //it's only way call Update is to cast obj to IState
        IState obj = new StateBase();
        obj.Update();
    }
}

Program.cs

class Program
{
    static void Main(string[] args)
    {
        //it's impossible to write Controller.IState p = new Controller.StateBase();
        //Controller.IState is hidden
        var p = new Controller.StateBase();
        //p.Update(); //is not accessible
    }
}

Well, what about inheritance?

We need to use technique described in Since explicit interface member implementations cannot be declared virtual and mark IState as protected to give possibility to derive from Controller too.

Controller.cs

public class Controller
{
    protected interface IState
    {
        void Update();
    }

    public class StateBase : IState
    {
        void IState.Update() { OnUpdate(); }
        protected virtual void OnUpdate()
        {
            Console.WriteLine("StateBase.OnUpdate()");
        }
    }

    public Controller()
    {
        IState obj = new PlayerIdleState();
        obj.Update();
    }
}

PlayerIdleState.cs

public class PlayerIdleState: Controller.StateBase
{
    protected override void OnUpdate()
    {
        base.OnUpdate();
        Console.WriteLine("PlayerIdleState.OnUpdate()");
    }
}

And finally example how to test class Controller throw inheritance: ControllerTest.cs

class ControllerTest: Controller
{
    public ControllerTest()
    {
        IState testObj = new PlayerIdleState();
        testObj.Update();
    }
}

Hope I cover all cases and my answer was useful.


You can get close to C++ "friend" with the C# keyword "internal".