223

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)

Community
  • 1
  • 1
Ash
  • 60,973
  • 31
  • 151
  • 169
  • 5
    i feel protected internal is a good compromise.. – Gulzar Nazim Oct 15 '08 at 03:39
  • 3
    It's not too confusing is it? As I said above the GOF book uses it quite often in examples. To me it's no more confusing then internal. – Ash Oct 15 '08 at 03:40
  • 2
    It's easy to answer: C# offers "internal" as access modifier which grants access to the all the code in the same module/assembly. This removes the need for something like friend. In Java the keyword "protected" behaves similarly w.r.t. access from the same package. – sellibitze Feb 16 '10 at 13:19
  • 2
    @sellibitze, I mention the differences with internal in the question. The problem with Interanl is that all classes in the assembly can access the internal members. This breaks encapsulation as maany of these classes may not need access. – Ash Feb 17 '10 at 00:44
  • _"why this was left out of C#"_ -- By saying that, the OP implicitly compares C# to C++. But why should C++ be the measuring tape for C#? Why should C# have to be anything like C++? It *could* be... but it simply isn't. – stakx - no longer contributing Oct 21 '12 at 09:29
  • 7
    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 Oct 23 '09 at 13:01
  • 1
    Because Microsoft did not have the philosophy your friends should see your private parts. – jaybers Aug 23 '15 at 02:22
  • Don't be so quick to dismiss `internal`. My experience is that the friend relationship is usually between two closely related classes (list and node, factory and widget, etc.) that are convenient to split into a separate assembly. Maybe it's a little weird that your two lists might have access to each other's nodes, but it's not like you have to make those properties or methods available to external/client code. This is a little weird for people who are used to writing single monolithic projects, but there are actually a lot of benefits of separating assemblies. – GrandOpener Oct 03 '15 at 19:58

22 Answers22

112

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.

Community
  • 1
  • 1
Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83
  • ...and the corresponding entry in the FQA: http://yosefk.com/c++fqa/friend.html#fqa-14.2 – Josh Lee Dec 16 '09 at 12:16
  • 30
    +1 for "*Using friend is not about violating the encapsulation, but on the contrary it's about enforcing it*" – Nawaz Feb 27 '12 at 05:47
  • 3
    A matter of semantic opinion I think; and perhaps related to the exact situation in question. Making a class a `friend` gives it access to ALL of your private members, even if you only need to let it set one of them. There is a strong argument to be made that making fields available to another class that doesn't need them counts as "violating encapsulation." There are places in C++ where it is necessary (overloading operators), but there is an encapsulation tradeoff that needs to be carefully considered. It seems the C# designers felt that tradeoff was not worth it. – GrandOpener Oct 03 '15 at 20:39
  • 3
    Encapsulation is about enforcing invariants. When we define a class as friend to another, we say explicitly that the two classes are strongly tied regarding the management of the invariants of the first one. Having the class made friend is still better than exposing all attributes directly (as public field) or through setters. – Luc Hermitte Oct 03 '15 at 21:35
  • 3
    Exactly. When you want to use friend but can't, you're forced to use internal or public, which are much more open to being poked at by things that shouldn't. Especially in a team environment. – Hatchling Feb 28 '17 at 20:55
70

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.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
  • 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 Oct 15 '08 at 03:47
  • 1
    What fundamental attributes are undermined? What relationships are broken? I'd like to understand what you're talking about. Thanks in advance! – Esteban Araya Oct 15 '08 at 04:02
  • 6
    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 Oct 15 '08 at 05:41
  • 176
    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 Oct 15 '08 at 17:19
  • 21
    Anders should be praised for the features he left out not the ones he included. – Mehrdad Afshari Apr 16 '09 at 12:26
  • 1
    You still can use "friend" but you can apply it to assemblies instead allowing different libraries to share internal classes. – Quibblesome Oct 23 '09 at 13:06
  • 21
    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 Oct 23 '09 at 13:11
  • 27
    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 Jan 20 '10 at 05:16
  • 4
    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 Jan 21 '10 at 12:13
  • @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 Feb 16 '10 at 12:17
  • 4
    @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. – Powerlord Feb 17 '10 at 14:21
  • 5
    Friend is required to implement some most basic design patterns. Generally, it is needed when more than one class needs to work together, like in e.g. manager/managed pattern. Lack of friend makes me often use hacks like making privates public. – kaalus Oct 20 '11 at 17:14
  • 8
    I think quite the opposite. If an assembly has 50 classes, if 3 of those classes use some utility class, then today, your only option is to mark that utility class as "internal". In doing so, you not only make it available for use to the 3 classes, but to the rest of the classes in the assembly. What if all you wanted to do is provide finer-grained access such that only the three classes in question had access to the utility class. It actually makes it more object oriented because it improves encapsulation. – zumalifeguard Oct 30 '11 at 01:21
  • "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." - this is not an argument why it undermines OOP. Python has no need for privacy at all: rather it depends on an accepted naming scheme to describe what can be easily accessed an what cannot. Yet it is very much an OOP language. – paul23 Mar 05 '17 at 23:38
  • 1
    Not sure how serious your kidding about C++' "pseudo OO" and C#' "pure OO" is, but what's for sure is that object orientedness does in no way imply classes, especially _not_ member functions, and super extremespecially not access modifiesr like `private` or `public`. Classes and restricted members are just one method to implement OOP. Classic, related read on C++ regarding members and non-members: [How non member functions improve encapsulation](http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197) – Sebastian Mach Oct 30 '17 at 16:45
  • "it is rare that you will be distributing your code to 3rd party developers not though a DLL" How true does this remain ten years later with the rise of libraries distributed as free software and maintained on Microsoft GitHub? – Damian Yerrick Jul 03 '18 at 14:10
  • But sometimes, I've come across that I need this one member to be private, except for one class. I would like to do a friend class, but instead I have to give some public scope access, either make the member public, or if it's a field or property, make some public handler for it. How does making something that should be private, public better than making it public to only one class? – AustinWBryan Jul 24 '18 at 10:55
  • I think a good thing for any C++ programmer to keep in mind is that once two classes are friends, they really aren't truly two separate classes anymore, they've become one class implemented in two parts (though each part can exist without the other). They're pretty much the same thing as "partial" classes in C#. – John Thoits Feb 06 '21 at 19:46
51

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
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 4
    good hint, as probably often people looking for friend want to find a way to unit test with the ability to have more internal 'knowledge'. – SwissCoder Oct 09 '12 at 11:22
16

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.

max_cn
  • 181
  • 1
  • 5
  • This is an awesome answer that needs more upvotes. – KthProg Apr 19 '17 at 15:30
  • @max_cn This is a really nice solution, but I cant see a way to get this working with mocking frameworks for unit testing. Any suggestions? – Steve Land Nov 28 '18 at 15:46
  • I'm a bit confused. If I wanted an external class to be able to call Update in your first example (private interface), how would I modify Controller to allow that to happen? – Anthony Feb 28 '20 at 18:53
  • @Steve Land, you can use inheritance as in ControllerTest.cs was shown. Add any necessary public methods in a derived test class and you will have access for all protected staff you have in base class. – max_cn Apr 24 '20 at 13:35
  • @AnthonyMonterrosa, we are hiding Update from ALL external resources so why you want to share it with someone ;)? Sure you can add some public method to access private members but it will be like a backdoor for any other classes. Anyway, if you need it for testing purposes - use inheritance to make something like ControllerTest class to make any testing cases there. – max_cn Apr 24 '20 at 13:48
  • This is a massively verbose and convoluted way to achieve an inferior effect of what "friend" provides (one can still cast to interface and call any functions they want). Lack of friend in C# is biting me almost daily in my everyday work. "Pure OOP" arguments are simply wrong: sometimes two classes need to have a private shared state. Friend provides for that. "Pure OOP" does not. – kaalus Dec 28 '20 at 17:07
  • @kaalus All other classes, except the Controller class in this case, don't know about this private/protected interface so they can't cast to it. Also this solution has advantages over a friend declaration: You can open a specific part on the class to the private interface, so your "friend" class can only use the specific part of it. This will then also be documented in the interface definition. – Daniel Bauer Mar 21 '22 at 09:05
13

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
  • 7,566
  • 3
  • 34
  • 38
  • 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 Oct 15 '08 at 03:44
  • 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 Oct 15 '08 at 03:53
  • 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 Dec 14 '09 at 19:13
  • 3
    The problem with the interface approach *of replacing 'Friend'* is for an object to expose an interface, that means anyone can cast the object to that interface and have access to the methods! Scoping the interface to internal, protected or private doesn't work either as if that worked, you could just scope the method in question! Think about a mother and child in a shopping mall. Public is everyone in the world. Internal is just the people in the mall. Private is just the mother or the child. 'Friend' is something between the mother and daughter only. – Mark A. Donohoe Jul 07 '11 at 18:01
  • 1
    Here's one: http://stackoverflow.com/questions/5921612/workaround-for-an-use-case-of-friend-classes-in-c-sharp As I come from C++ background, lack of friend drives me insane almost daily. In my few years with C# I have made literally hundreds of methods public where they could be private and safer instead, all because of lack of friend. Personally I think friend is the most important thing that should be added to .NET – kaalus Nov 12 '12 at 23:35
  • Interfaces do this well. Well structured code should protect against accidental misuse, not against intentional malice. If you strictly hand out one interface externally, and the user reads your code and steals away a interface documented as for internal use, that's not a flaw in your code, that's someone intentionally being a jerkface. No matter what you do, someone could always use unsafe code to play with the bits regardless. You job in writing code is making something that's **hard** to use incorrectly. It's **impossible** to make something that is **impossible** to use incorrectly. – GrandOpener Oct 03 '15 at 20:17
13

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

Nick Alexeev
  • 1,688
  • 2
  • 22
  • 36
8

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

jeffm
  • 3,120
  • 1
  • 34
  • 57
  • 3
    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 Oct 15 '08 at 03:35
  • 3
    @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 Jan 21 '10 at 12:15
8

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
  • 97
  • 1
  • 1
  • C# is missing deterministic destruction because it's slower than garbage collection. Deterministic destruction takes time for every object created, whereas garbage collection only takes time for the currently live objects. In most cases, this is faster, and the more short-lived objects there are in the system, the relatively faster garbage collection gets. – Edward Robertson Sep 16 '11 at 17:51
  • 1
    @Edward Robertson Deterministic destruction does not take any time unless there is a destructor defined. But in this case, garbage collection is much worse, because then you need to use a finalizer, which is slower and nondeterministic. – kaalus Oct 20 '11 at 17:19
  • 1
    ... and memory is not the only kind of resource. People often act as if it was true. – cubuspl42 Aug 24 '15 at 14:15
8

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
  • 17,578
  • 6
  • 88
  • 115
  • I was going to make a comment about "friend" being useful for factory classes, but I'm glad to see that someone has already made it. – Edward Robertson Sep 16 '11 at 17:48
7

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
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 7
    -1. `friend` is not a bad thing; on the contrary, it is far better than `internal`. And Nelson's explanation is bad and incorrect. – Nawaz Feb 27 '12 at 05:46
4

Stop making excuses for this limitation. friend is bad, but internal is good? they are the same thing, only that friend gives you more precise control over who is allowed to access and who isn't.

This is to enforce the encapsulation paradigm? so you have to write accessor methods and now what? how are you supposed to stop everyone (except the methods of class B) from calling these methods? you can't, because you can't control this either, because of missing "friend".

No programming language is perfect. C# is one of the best languages I've seen, but making silly excuses for missing features doesn't help anyone. In C++, I miss the easy event/delegate system, reflection (+automatic de/serialization) and foreach, but in C# I miss operator overloading (yeah, keep telling me that you didn't need it), default parameters, a const that cannot be circumvented, multiple inheritance (yeah, keep telling me that you didn't need it and interfaces were a sufficient replacement) and the ability to decide to delete an instance from memory (no, this is not horribly bad unless you are a tinkerer)

Algoman
  • 1,905
  • 16
  • 16
  • In C# you can overload most operators. You can't overload assignment operators, but on the other hand you can override `||`/`&&` while keeping them short circuiting. Default parameters were added in C# 4. – CodesInChaos Nov 20 '11 at 10:11
3

I will answer only "How" question.

There are so many answers here, however I would like to propose kind of "design pattern" to achieve that feature. I will use simple language mechanism, which includes:

  • Interfaces
  • Nested class

For example we have 2 main classes: Student and University. Student has GPA which only university allowed to access. Here is the code:

public interface IStudentFriend
{
    Student Stu { get; set; }
    double GetGPS();
}

public class Student
{
    // this is private member that I expose to friend only
    double GPS { get; set; }
    public string Name { get; set; }

    PrivateData privateData;

    public Student(string name, double gps) => (GPS, Name, privateData) = (gps, name, new PrivateData(this);

    // No one can instantiate this class, but Student
    // Calling it is possible via the IStudentFriend interface
    class PrivateData : IStudentFriend
    {
        public Student Stu { get; set; }

        public PrivateData(Student stu) => Stu = stu;
        public double GetGPS() => Stu.GPS;
    }

    // This is how I "mark" who is Students "friend"
    public void RegisterFriend(University friend) => friend.Register(privateData);
}

public class University
{
    var studentsFriends = new List<IStudentFriend>();

    public void Register(IStudentFriend friendMethod) => studentsFriends.Add(friendMethod);

    public void PrintAllStudentsGPS()
    {
        foreach (var stu in studentsFriends)
            Console.WriteLine($"{stu.Stu.Name}: stu.GetGPS()");
    }
}

public static void Main(string[] args)
{
    var Technion = new University();
    var Alex     = new Student("Alex", 98);
    var Jo       = new Student("Jo", 91);

    Alex.RegisterFriend(Technion);
    Jo.RegisterFriend(Technion);
    Technion.PrintAllStudentsGPS();

    Console.ReadLine();
}
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Rami Yampolsky
  • 465
  • 4
  • 12
2

I have read many smart comments about "friend" keyword & i agree what it is useful thing, but i think what "internal" keyword is less useful, & they both still bad for pure OO programming.

What we have? (saying about "friend" I also saying about "internal")

  • is using "friend" makes code less pure regarding to oo?
  • yes;

  • is not using "friend" makes code better?

  • no, we still need to make some private relationships between classes, & we can do it only if we break our beautiful encapsulation, so it also isn`t good, i can say what it even more evil than using "friend".

Using friend makes some local problems, not using it makes problems for code-library-users.

the common good solution for programming language i see like this:

// c++ style
class Foo {
  public_for Bar:
    void addBar(Bar *bar) { }
  public:
  private:
  protected:
};

// c#
class Foo {
    public_for Bar void addBar(Bar bar) { }
}

What do you think about it? I think it the most common & pure object-oriented solution. You can open access any method you choose to any class you want.

Sergey K.
  • 24,894
  • 13
  • 106
  • 174
  • I'm not an OOP sentinel, but it looks like it solves everyone's gripes against friend and internal. But I would suggest using an attribute to avoid the extension of C#'s syntax: [PublicFor Bar] void addBar(Bar bar) { } ... Not that I'm sure that makes sense; I don't know how attributes work or whether they can fiddle with accessibility (they do a lot of other "magical" stuff). – Grault Mar 15 '13 at 08:28
2

There is the InternalsVisibleToAttribute since .Net 3 but I suspect they only added it to cater to test assemblies after the rise of unit testing. I can't see many other reasons to use it.

It works at the assembly level but it does the job where internal doesn't; that is, where you want to distribute an assembly but want another non-distributed assembly to have privileged access to it.

Quite rightly they require the friend assembly to be strong keyed to avoid someone creating a pretend friend alongside your protected assembly.

Chris Woodward
  • 382
  • 3
  • 12
1

The friendship may be simulated by separating interfaces and implementations. The idea is: "Require a concrete instance but restrict construction access of that instance".

For example

interface IFriend { }

class Friend : IFriend
{
    public static IFriend New() { return new Friend(); }
    private Friend() { }

    private void CallTheBody() 
    {  
        var body = new Body();
        body.ItsMeYourFriend(this);
    }
}

class Body
{ 
    public void ItsMeYourFriend(Friend onlyAccess) { }
}

In spite of the fact that ItsMeYourFriend() is public only Friend class can access it, since no one else can possibly get a concrete instance of the Friend class. It has a private constructor, while the factory New() method returns an interface.

See my article Friends and internal interface members at no cost with coding to interfaces for details.

Reuven Bass
  • 672
  • 1
  • 6
  • 16
  • Sadly friendship cannot be simulated in any possible way. See this question: http://stackoverflow.com/questions/5921612/workaround-for-an-use-case-of-friend-classes-in-c-sharp – kaalus Nov 12 '12 at 23:46
1

Some have suggested that things can get out of control by using friend. I would agree, but that doesn't lessen its usefulness. I'm not certain that friend necessarily hurts the OO paradigm any more than making all your class members public. Certainly the language will allow you to make all your members public, but it is a disciplined programmer that avoids that type of design pattern. Likewise a disciplined programmer would reserve the use of friend for specific cases where it makes sense. I feel internal exposes too much in some cases. Why expose a class or method to everything in the assembly?

I have an ASP.NET page that inherits my own base page, that in turn inherits System.Web.UI.Page. In this page, I have some code that handles end-user error reporting for the application in a protected method

ReportError("Uh Oh!");

Now, I have a user control that is contained in the page. I want the user control to be able to call the error reporting methods in the page.

MyBasePage bp = Page as MyBasePage;
bp.ReportError("Uh Oh");

It can't do that if the ReportError method is protected. I can make it internal, but it is exposed to any code in the assembly. I just want it exposed to the UI elements that are part of the current page (including child controls). More specifically, I want my base control class to define the exact same error reporting methods, and simply call methods in the base page.

protected void ReportError(string str) {
    MyBasePage bp = Page as MyBasePage;
    bp.ReportError(str);
}

I believe that something like friend could be useful and implemented in the language without making the language less "OO" like, perhaps as attributes, so that you can have classes or methods be friends to specific classes or methods, allowing the developer to provide very specific access. Perhaps something like...(pseudo code)

[Friend(B)]
class A {

    AMethod() { }

    [Friend(C)]
    ACMethod() { }
}

class B {
    BMethod() { A.AMethod() }
}

class C {
    CMethod() { A.ACMethod() }
}

In the case of my previous example perhaps have something like the following (one can argue semantics, but I'm just trying to get the idea across):

class BasePage {

    [Friend(BaseControl.ReportError(string)]
    protected void ReportError(string str) { }
}

class BaseControl {
    protected void ReportError(string str) {
        MyBasePage bp = Page as MyBasePage;
        bp.ReportError(str);
    }
}

As I see it, the friend concept has no more risk to it than making things public, or creating public methods or properties to access members. If anything friend allows another level of granularity in accessibility of data and allows you to narrow that accessibility rather than broadening it with internal or public.

Scott Forbes
  • 166
  • 2
  • 11
1

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
  • 14,281
  • 7
  • 61
  • 70
  • 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 Oct 15 '08 at 03:39
1

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
  • 11
  • 1
1

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!

Christo
  • 8,729
  • 2
  • 22
  • 16
0

B.s.d.

It was stated that, friends hurts pure OOness. Which I agree.

It was also stated that friends help encapsulation, which I also agree.

I think friendship should be added to the OO methodology, but not quite as it in C++. I'd like to have some fields/methods that my friend class can access, but I'd NOT like them to access ALL my fields/methods. As in real life, I'd let my friends access my personal refrigerator but I'd not let them to access my bank account.

One can implement that as followed

    class C1
    {
        private void MyMethod(double x, int i)
        {
            // some code
        }
        // the friend class would be able to call myMethod
        public void MyMethod(FriendClass F, double x, int i)
        {
            this.MyMethod(x, i);
        }
        //my friend class wouldn't have access to this method 
        private void MyVeryPrivateMethod(string s)
        {
            // some code
        }
    }
    class FriendClass
    {
        public void SomeMethod()
        {
            C1 c = new C1();
            c.MyMethod(this, 5.5, 3);
        }
    }

That will of course generate a compiler warning, and will hurt the intellisense. But it will do the work.

On a side note, I think that a confident programmer should do the testing unit without accessing the private members. this is quite out of the scope, but try to read about TDD. however, if you still want to do so (having c++ like friends) try something like

#if UNIT_TESTING
        public
#else
        private
#endif
            double x;

so you write all your code without defining UNIT_TESTING and when you want to do the unit testing you add #define UNIT_TESTING to the first line of the file(and write all the code that do the unit testing under #if UNIT_TESTING). That should be handled carefully.

Since I think that unit testing is a bad example for the use of friends, I'd give an example why I think friends can be good. Suppose you have a breaking system (class). With use, the breaking system get worn out and need to get renovated. Now, you want that only a licensed mechanic would fix it. To make the example less trivial I'd say that the mechanic would use his personal (private) screwdriver to fix it. That's why mechanic class should be friend of breakingSystem class.

ehud117
  • 1
  • 1
  • 2
    That FriendClass parameter doesn't serve as access control: you can call `c.MyMethod((FriendClass) null, 5.5, 3)` from any class. – Tara McGrew Sep 28 '12 at 23:25
0

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
  • 2,356
  • 1
  • 16
  • 23
  • I agree. I never need the friend keyword. It's generally used to solve complex maintenance issues. – Edouard A. Jan 19 '09 at 16:29
  • 7
    Operator overloading, anyone?? – We Are All Monica Sep 22 '09 at 01:27
  • 3
    how many times you found a good case for operator overloading seriously ? – bashmohandes Sep 30 '09 at 22:17
  • I routinely overload operator(), operator<<, and a few others. – Max Lybbert Jan 22 '10 at 10:04
  • 8
    I'll give you a very simple case that completely debunks your 'design issue' comment. Parent-Child. A parent owns its children. A child in the parent's 'Children' collection is owned by that parent. The Parent property's setter on Child shouldn't be settable by just anyone. It needs to be assigned when and only when the child is added to the parent's Children collection. tIf it's public, anyone can change it. Internal: anyone in that assembly. Private? No one. Making the setter a friend to parent eliminates those cases and still keeps your classes separate, but tightly related. Huzzah!! – Mark A. Donohoe Jul 07 '11 at 17:54
  • 2
    There are a lot of such cases, such as most basic manager/managed pattern. There is another question on SO and no one figured a way how to do it without a friend. Not sure what makes people think that one class "will always suffice". Sometimes more than one class needs to work together. – kaalus Oct 20 '11 at 17:17
  • The situation described by "Marquel"is the perfect example for the need of friend. This will be the only choice if the parent has list of childs,the list should be in some order and every child should have their appropriate list index . Then obviously the parent should do everything of that child. – prabhakaran May 29 '12 at 14:21
0

The friendship may also be simulated by using "agents" - some inner classes. Consider following example:

public class A // Class that contains private members
{
  private class Accessor : B.BAgent // Implement accessor part of agent.
  {
    private A instance; // A instance for access to non-static members.
    static Accessor() 
    { // Init static accessors.
      B.BAgent.ABuilder = Builder;
      B.BAgent.PrivateStaticAccessor = StaticAccessor;
    }
    // Init non-static accessors.
    internal override void PrivateMethodAccessor() { instance.SomePrivateMethod(); }
    // Agent constructor for non-static members.
    internal Accessor(A instance) { this.instance = instance; }
    private static A Builder() { return new A(); }
    private static void StaticAccessor() { A.PrivateStatic(); }
  }
  public A(B friend) { B.Friendship(new A.Accessor(this)); }
  private A() { } // Private constructor that should be accessed only from B.
  private void SomePrivateMethod() { } // Private method that should be accessible from B.
  private static void PrivateStatic() { } // ... and static private method.
}
public class B
{
  // Agent for accessing A.
  internal abstract class BAgent
  {
    internal static Func<A> ABuilder; // Static members should be accessed only by delegates.
    internal static Action PrivateStaticAccessor;
    internal abstract void PrivateMethodAccessor(); // Non-static members may be accessed by delegates or by overrideable members.
  }
  internal static void Friendship(BAgent agent)
  {
    var a = BAgent.ABuilder(); // Access private constructor.
    BAgent.PrivateStaticAccessor(); // Access private static method.
    agent.PrivateMethodAccessor(); // Access private non-static member.
  }
}

It could be alot simpler when used for access only to static members. Benefits for such implementation is that all the types are declared in the inner scope of friendship classes and, unlike interfaces, it allows static members to be accessed.

Aberro
  • 620
  • 6
  • 10