views:

7265

answers:

14

The C++ friend keyword allows a class A to designate class B as it's 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 the friend keyword 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, friend allows you to give access to a class to just one other class.)

+6  A: 

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

jeffm
Close, but not quite there. I suppose it depends on how you structure your assemblies/classes, but it would be more elegant to minimise the number of classes given access using friend. FOr example in a utility/helper assembly, not all classes should have access to internal members.
Ash
@Ash: You need to get used to it but once you see assemblies as the fundamental building block of your applications, `internal` makes a great deal more sense and provides an excellent trade-off between encapsulation and utility. Java’s default access is even better, though.
Konrad Rudolph
+1  A: 

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.

Stewart Johnson
I think the compiler could support it reasonably easily at least between classes within an assembly. Just a matter of relaxing access checking for the friend class on the target class.Friend between classes in external assemblies may need more fundamental changes to the CLR perhaps.
Ash
+5  A: 

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#.

Parappa
Good point. Did you have a chance to look at the earlier SO question (asked by monoxide and linked above?. I'd be interested in how best to solve that in C#?
Ash
I'm not sure exactly how to do it in C#, but I think Jon Skeet's answer to monoxide's question points in the right direction. C# allows nested classes. I haven't actually tried to code out and compile a solution, though. :)
Parappa
I feel that the mediator pattern is a good example of where friend would be nice. I refactor my Forms to have a mediator. I want my form to be able to call the "event" like methods in the mediator, but I don't really want other classes calling those "event" like methods. The "Friend" feature would give the form access to the methods with out opening it up to everything else in the assembly.
Vaccano
+20  A: 

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 dose get the job done. Remember that it is rare that you will be distributing your code to 3rd party developers not though 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.

nlaq
So it seems that the reason the 'internal' keyword is in C# but 'friend' is not, is that internal is more explicit then friend. I guess as soon as you see internal, you know immediately it's possible that another class could access them.
Ash
What fundamental attributes are undermined? What relationships are broken? I'd like to understand what you're talking about. Thanks in advance!
Esteban Araya
I don't think friend was left out for "OO purity". I think it's more likely because the C# is translated to IL when you compile, and the other types you may want to friend are available. It's the same way C++ generics are entirely compile-time, and C#'s aren't.
Stewart Johnson
C# 'internal' is actually hurting encapsulation much more than C++ 'friend'. With "friendship", the owner explicitely gives the permission to whoever it wants. "Internal" is an open ended concept.
Nemanja Trifunovic
Anders should be praised for the features he left out not the ones he included.
Mehrdad Afshari
You still can use "friend" but you can apply it to assemblies instead allowing different libraries to share internal classes.
Quibblesome
I disagree that C#'s internal hurts incapsulation though. The opposite in my opinion. You can use it to create an encapsulated ecosystem within an assembly. A number of objects can share internal types within this ecosystem that are not exposed to the rest of the application. I use the "friend" assembly tricks to create unit test assemblies for these objects.
Quibblesome
This doesn't make sense. `friend` doesn't let arbitrary classes or functions access private members. It lets the specific functions or classes that were marked as friend do so. The class owning the private member still controls access to it 100%. You might as well argue that public member methods. Both ensure that the methods specifically listed in the class are given access to private members of the class.
jalf
No, that answer is factually wrong, and other threads on SO already explain why, e.g. http://stackoverflow.com/questions/17434/when-should-you-use-friend-in-c/17505#17505
Konrad Rudolph
@Konrad: The link you provided talks specifically to encapsulation whereas @NelsonLaQuet generalizes OOP in regard to `friend`. Although your link might be correct in and of itself, comparing it to this answer feels like comparing apples and oranges, or at least red apples and green apples.
John K
@Nemanja Trifunovic: '"Internal" is an open ended concept.' Not really. Since you the programmer control what classes are in your assemblies, you implicitly control which classes can access it. However, it's a bad idea to let classes have direct access to your stuff anyway, which is why .NET introduced the properties syntax.
R. Bemrose
+6  A: 

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??

bashmohandes
I agree. I never need the friend keyword. It's generally used to solve complex maintenance issues.
Edouard A.
Operator overloading, anyone??
jnylen
how many times you found a good case for operator overloading seriously ?
bashmohandes
I routinely overload operator(), operator<<, and a few others.
Max Lybbert
+13  A: 

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.

Marc Gravell
+6  A: 

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.

JaredPar
+21  A: 

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 lite.

Luc Hermitte
...and the corresponding entry in the FQA: http://yosefk.com/c++fqa/friend.html#fqa-14.2
jleedev
+3  A: 

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.

Andy Dent
+4  A: 

Friends are not necessarily bad. Just like in real life, you just have to choose them carefully.

+5  A: 

I can certainly see scenarios where they can be very useful, as already mentioned Unit Testing.

But do you really want your friends accessing your privates?

danswain
+1  A: 

C# is missing the "friend" keyword for the same reason its missing deterministic destruction. Changing conventions makes people feel smart, as if their new ways are superior to someone else' old ways. It's all about pride.

Saying that "friend classes are bad" is as short-sighted as other unqualified statements like "don't use gotos" or "Linux is better than Windows".

The "friend" keyword combined with a proxy class is a great way to only expose certain parts of a class to specific other class(es). A proxy class can act as a trusted barrier against all other classes. "public" doesn't allow any such targeting, and using "protected" to get the effect with inheritance is awkward if there really is no conceptual "is a" relationship.

Matthew
A: 

you can keep it private and use reflection to call functions. Test framework can do this if you ask it to test a private function

vishal
A: 

Because no one likes C#, so it has no friends.

samoz