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

Viewed 60961

The C++ friend keyword allows a class A to designate class B as its friend. This allows Class B to access the private/protected members of class A.

I've never read anything as to why this was left out of C# (and VB.NET). Most answers to this earlier StackOverflow question seem to be saying it is a useful part of C++ and there are good reasons to use it. In my experience I'd have to agree.

Another question seems to me to be really asking how to do something similar to friend in a C# application. While the answers generally revolve around nested classes, it doesn't seem quite as elegant as using the friend keyword.

The original Design Patterns book uses it regularly throughout its examples.

So in summary, why is friend missing from C#, and what is the "best practice" way (or ways) of simulating it in C#?

(By the way, the internal keyword is not the same thing, it allows all classes within the entire assembly to access internal members, while friend allows you to give a certain class complete access to exactly one other class)

22 Answers

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

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

Friend is extremely useful when writing unit test.

Whilst that comes at a cost of polluting your class declaration slightly, it's also a compiler-enforced reminder of what tests actually might care about the internal state of the class.

A very useful and clean idiom I've found is when I have factory classes, making them friends of the items they create which have a protected constructor. More specifically, this was when I had a single factory responsible for creating matching rendering objects for report writer objects, rendering to a given environment. In this case you have a single point of knowledge about the relationship between the report-writer classes (things like picture blocks, layout bands, page headers etc.) and their matching rendering objects.

This is actually not an issue with C#. It's a fundamental limitation in IL. C# is limited by this, as is any other .Net language that seeks to be verifiable. This limitation also includes managed classes defined in C++/CLI (Spec section 20.5).

That being said I think that Nelson has a good explanation as to why this is a bad thing.

I suspect it has something to do with the C# compilation model -- building IL the JIT compiling that at runtime. i.e.: the same reason that C# generics are fundamentally different to C++ generics.

I used to regularly use friend, and I don't think it's any violation of OOP or a sign of any design flaw. There are several places where it is the most efficient means to the proper end with the least amount of code.

One concrete example is when creating interface assemblies that provide a communications interface to some other software. Generally there are a few heavyweight classes that handle the complexity of the protocol and peer peculiarities, and provide a relatively simple connect/read/write/forward/disconnect model involving passing messages and notifications between the client app and the assembly. Those messages / notifications need to be wrapped in classes. The attributes generally need to be manipulated by the protocol software as it is their creator, but a lot of stuff has to remain read-only to the outside world.

It's just plain silly to declare that it's a violation of OOP for the protocol / "creator" class to have intimate access to all of the created classes -- the creator class has had to bit munge every bit of data on the way up. What I've found most important is to minimize all the BS extra lines of code the "OOP for OOP's Sake" model usually leads to. Extra spaghetti just makes more bugs.

Do people know that you can apply the internal keyword at the attribute, property, and method level? It's not just for the top level class declaration (though most examples seem to show that.)

If you have a C++ class that uses the friend keyword, and want to emulate that in a C# class: 1. declare the C# class public 2. declare all the attributes/properties/methods that are protected in C++ and thus accessible to friends as internal in C# 3. create read only properties for public access to all internal attributes and properties

I agree it's not 100% the same as friend, and unit test is a very valuable example of the need of something like friend (as is protocol analyzer logging code). However internal provides the exposure to the classes you want to have exposure, and [InternalVisibleTo()] handles the rest -- seems like it was born specifically for unit test.

As far as friend "being better because you can explicitely control which classes have access" -- what in heck are a bunch of suspect evil classes doing in the same assembly in the first place? Partition your assemblies!

If you are working with C++ and you find your self using friend keyword, it is a very strong indication, that you have a design issue, because why the heck a class needs to access the private members of other class??

Related