Related
I am not sure if this even fits on StackOverflow, or maybe rather on Programmers#StackExchange. If this should rather go there, let me know in a comment below and I will move it :)
Anyway - back to the point. I have never done much programming using interfaces and Constructor/Property dependency injection etc. So I do know too much about it. I have been reading some articles though, mainly this, and found this an interesting technique to make my software more flexible and testable.
So off I go and start refactoring an existing application (C#), and I come across a dilemma, which one of the 2 below choices is better:
Choice 1 - minimum dependency requirements in a function. Leave some injection for constructor (implementation decision when using the interface)
public interface IDriver
{
bool Start();
bool Stop();
bool Read(uint[] signal1, uint[] signal2);
}
public class MyDriver : IDriver
{
public MyDriver(ISettings settings)
{
//remember ISettings in a local var
}
//interface implementation
}
Choice 2 - all required dependencies in a function call.
public interface IDriver
{
bool Start();
bool Stop();
bool Read(ISettings settings, uint[] signal1, uint[] signal2);
}
public class MyDriver : IDriver
{
//implementation of the interface
}
Now the choice 2 might be wrong , right? because some implementations might actually not need the ISettings to work. The fact that my implementation of IDriver uses ISettings at the moment does not mean that it will in a year or so, so the logical approach would be to use method 1.
So my question would be: how strict should I make my interfaces, and how to not get mixed up between an interface and an implementation? I do not want the implementation to influence how I design my interfaces.
Also, does anyone know of good articles about the topic?
Thanks.
Interfaces should be defined and owned by the clients that consume the interfaces. As Agile Principles, Patterns, and Practices explain, "clients […] own the abstract interfaces" (chapter 11). Thus, if the client only requires this to work (your option 1):
public interface IDriver
{
bool Start();
bool Stop();
bool Read(uint[] signal1, uint[] signal2);
}
then that should be the interface. Everything else is an implementation detail, and should go in the constructor.
More than strictness, it is a question of contractual necessity.
Is ISettings contractually needed for your Read functionality? Probably NO.
think of it as no different than the signal1 and signal2 variables. The reason you have signal1 and signal2 in the Read method definition of the Interface is because they are part of the contract and mandatory for every implementation of the interface to use as inputs.
But ISettings sounds like something that a particular implementation would need whereas some others won't. (like Loggers, CacheManagers, Repositories etc.)
So you're right and more often than not, Approach #1 will be preferable. It keeps the interfaces clean & confined to the exact contractual input/outputs.
Thorough study of system requirment solves many problems and helps you design the application with more confidence. So first, think more and more until you reach a point when you can argue and reason about what you're going to do.
Secondly IMHO, the both approaches are OK. The first one as 'raja' pointed out is clean and succient and I don't repeat what he says again. But consider this situation: if later the IDriver implementors somehow need to be configured. Then passing some sort of setting to them solves many problems. Even if at the current moment you think it is unneccessary (and I admit it is what YAGNI principle says), you can provide empty setting (NullObject pattern):
public Driver : IDriver
{
public bool Read(ISettings settings, uint[] signal1, uint[] signal2)
{
if (settings.PreventSomeThing)
{
.....
}
}
}
public NullSetting : ISetting
{
public bool PreventSomething = false;
....
}
Basically, I have the following scenario:
public abstract class FooBase<T> where T : FooBase<T>
{
public bool IsSpecial { get; private set; }
public static T GetSpecialInstance()
{
return new T() { IsSpecial = true };
}
}
public sealed class ConcreteFooA : FooBase<ConcreteFooA> { ... }
public sealed class ConcreteFooB : FooBase<ConcreteFooB> { ... }
But, the problem I see here is that I could have done ConcreteFooB : FooBase<ConcreteFooA> { ... }, which would completely mess up the class at runtime (it wouldn't meet the logic I'm trying to achieve), but still compile correctly.
Is there some way I haven't thought of to enforce the generic, T, to be whatever the derived class is?
Update: I do end up using the generic parameter, T, in the FooBase<T> class, I just didn't list every method that has it as an out and in parameter, but I do have a use for T.
To answer your question:
No, there is no compile time solution to enforce this.
There are a couple of ways to enforce this rule:
Unit Testing - You could write up a unit test (or unit tests) to ensure that the compiled types are passing themselves in as the generic parameter.
Code Analysis - You could create a custom code analysis rule that enforces this, and then set that rule as an error (vs warning). This would be checked at compile-time.
FxCop Rule - Similar to the Code Analysis rule, except if you don't have a version of Visual Studio that has built-in support for Code Analysis, then you can use FxCop instead.
Of course, none of these rules are enforced on a standard compilation, but instead require additional tools (Unit Testing, Code Analysis, FxCop). If someone took your code and compiled it without using these tools you'd run into the same issue... of course, at that point why is someone else compiling your code without running your unit tests or Code Analysis/FxCop rules?
Alternatively, and I don't recommend this, you could throw a run-time error. Why not? According to Microsoft:
If a static constructor throws an exception, the runtime will not
invoke it a second time, and the type will remain uninitialized for
the lifetime of the application domain in which your program is
running.
That really doesn't solve your issue. On top of that, throwing an exception during static initialization is a violation of Code Analysis CA1065:DoNotRaiseExceptionsInUnexpectedLocations. So, you're going in the wrong direction if you do this.
There is no compile-time way to enforce this, as far as I know. It can, however, be enforced using a run-time check. No unusual user actions would typically be able to cause this, (just incorrect coding) so it's similar to having Debug.Assert in places (and, in fact, you could implement it using that, if you like). E.g.
public abstract class FooBase<T> where T : FooBase<T>
{
protected FooBase()
{
Debug.Assert(this.GetType() == typeof(T));
}
}
I don't know why you have this as a requirement. I would first suggest that you go back and look at 'your object model and determine why you feel you need this requirement and determine if there's a better way to accomplish whatever it is you're trying to achieve.
I think I see one problem with what you have above: no generic parameters in your definitions/declarations of classes ConcreteFooA and ConcreteFooB.
It looks as though it may be better for you to create an interface IFooBase and have your concrete implementations implement the interface. In every instance where you want to work with an IFooBase, you'd use a variable of type IFooBase.
So:
public interface IFooBase { /* Interface contract... */ }
public class ConcreteFooA : IFooBase { /* Implement interface contract */ }
public class ConcreteFooB : IFooBase { /* Implement interface contract */ }
// Some class that acts on IFooBases
public class ActionClass
{
public ActionClass(IFooBase fooBase) { this._fooBase = foobase };
public DoSomething() { /* Do something useful with the FooBase */ }
// Or, you could use method injection on static methods...
public static void DoSomething(IFooBase fooBase) { /* Do some stuff... */ }
}
Just some ideas. But I don't think you can accomplish what you want to do with Generics alone.
It's not possible and it should not be, because according to L in SOLID:
Liskov substitution principle: “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program”.
So actually the compiler is doing what it was meant to do.
Maybe you need to change the design and implementation of your classes for example by employing a Behavioral Pattern. For instance if an object should present different algorithms for a specific calculation you could use Strategy Pattern.
But I can not advise on that since I am not aware what exactly you want to achieve.
Is it possible to define an Interface with optional implementation methods? For example I have the following interface definition as IDataReader in my core library:
public interface IDataReader<T> {
void StartRead(T data);
void Stop();
}
However, in my current implementations, the Stop() method has never been used or implemented. In all my implementation classes, this method has to be implemented with throw NotImplementedExcetion() as default:
class MyDataReader : IDataReader<MyData> {
...
public void Stop()
{
// this none implementaion looks like uncompleted codes
throw NotImplementedException();
}
Of course, I can remove the throw exception code and leave it empty.
When I designed this data reader interface, I thought it should provide a way to stop the reading process. Maybe we will use Stop() sometime in the future.
Anyway, not sure if it is possible to make this Stop() method as an optional implementation method? The only way I can think is to either to define two interfaces one with stop and another without such as IDataReader and IDataReader2. Another option is to break this one into to interfaces like this:
interface IDataReader<T> {
void StartRead(T data);
}
interface IStop {
void Stop();
}
In my implementation cases, I have to cast or use as IStop to check if my implementation supports Stop() method:
reader.StartRead(myData);
....
// some where when I need to stop reader
IStop stoppable = reader as IStop;
if (stoppable != null ) stoppable.Stop();
...
Still I have to write those codes. Any suggestions? Not sure if there is any way to define optional implementation methods in an interface in .Net or C#?
Interesting. I'll have to quote you here:
However, in my current
implementations, the Stop() method has
never been used or implemented. In all
my implementation classes, this method
has to be implemented with throw
NotImplementedExcetion() as default:
If this is the case, then you have two options:
Remove the Stop() method from the interface. If it isn't used by every implementor of the interface, it clearly does not belong there.
Instead of an interface, convert your interface to an abstract base class. This way there is no need to override an empty Stop() method until you need to.
Update The only way I think methods can be made optional is to assign a method to a variable (of a delegate type similar to the method's signature) and then evaluating if the method is null before attempting to call it anywhere.
This is usually done for event handlers, wherein the handler may or may not be present, and can be considered optional.
For info, another approach fairly common in the BCL is Supports* on the same interface, i.e.
bool SupportsStop {get;}
void Stop();
(examples of this, for example, in IBindingList).
I'm not pretending that it is "pure" or anything, but it works - but it means you now have two methods to implement per feature, not one. Separate interfaces (IStoppableReader, for example) may be preferable.
For info, if the implementation is common between all implementations, then you can use extension methods; for a trivial example:
public static void AddRange<T>(this IList<T> list, IEnumerable<T> items) {
foreach(T item in items) list.Add(item);
}
(or the equivalent for your interface). If you provide a more specialized version against the concrete type, then it will take precedence (but only if the caller knows about the variable as the concrete type, not the interface). So with the above, anyone knowingly using a List<T> still uses List<T>'s version of AddRange; but if the have a List<T> but only know about it as IList<T>, it'll use the extension method.
If the method is inappropriate for your implementation, throw InvalidOperationException just like most iterators do when you call Reset on them. An alternative is NotSupportedException which tends to be used by System.IO. The latter is more logical (as it has nothing to do with the current state of the object, just its concrete type) but the former is more commonly used in my experience.
However, it's best to only put things into an interface when you actually need them - if you're still in a position where you can remove Stop, I would do so if I were you.
There's no unified support for optional interface members in the language or the CLR.
If no classes in your code actually implement Stop(), and you don't have definite plans to do so in the future, then you don't need it in your interface. Otherwise, if some but not all of your objects are "stoppable", then the correct approach is indeed to make it a separate interface such as IStoppable, and the clients should then query for it as needed.
If your implementation does not implement the interface method Stop, then it breaks obviousily the contract that comes with your interface. Either you implement the Stop method appropriately (not by throwing an Exception and not by leaving it empty) or you need to redesign your interface (so to change the contract).
Best Regards
C# version 4 (or vNext) is considering default implementation for interfaces - I heard that on channel9 a few months ago ;).
Interfaces with default implementation would behave somewhat like abstract base classes. Now that you can inherit multiple interfaces this could mean that C# might get multiple inheritance in form of interfaces with default implementations.
Until then you might get away with extension methods...
Or your type could make use of the delegates.
interface IOptionalStop
{
Action Stop { get; }
}
public class WithStop : IOptionalStop
{
#region IOptionalStop Members
public Action Stop
{
get;
private set;
}
#endregion
public WithStop()
{
this.Stop =
delegate
{
// we are going to stop, honest!
};
}
}
public class WithoutStop : IOptionalStop
{
#region IOptionalStop Members
public Action Stop
{
get;
private set;
}
#endregion
}
public class Program
{
public static string Text { get; set; }
public static void Main(string[] args)
{
var a = new WithStop();
a.Stop();
var o = new WithoutStop();
// Stop is null and we cannot actually call it
a.Stop();
}
}
I have a class with some abstract methods, but I want to be able to edit a subclass of that class in the designer. However, the designer can't edit the subclass unless it can create an instance of the parent class. So my plan is to replace the abstract methods with stubs and mark them as virtual - but then if I make another subclass, I won't get a compile-time error if I forget to implement them.
Is there a way to mark the methods so that they have to be implemented by subclasses, without marking them as abstract?
Well you could do some really messy code involving #if - i.e. in DEBUG it is virtual (for the designer), but in RELEASE it is abstract. A real pain to maintain, though.
But other than that: basically, no. If you want designer support it can't be abstract, so you are left with "virtual" (presumably with the base method throwing a NotImplementedException).
Of course, your unit tests will check that the methods have been implemented, yes? ;-p
Actually, it would probably be quite easy to test via generics - i.e. have a generic test method of the form:
[Test]
public void TestFoo() {
ActualTest<Foo>();
}
[Test]
public void TestBar() {
ActualTest<Bar>();
}
static void ActualTest<T>() where T : SomeBaseClass, new() {
T obj = new T();
Assert.blah something involving obj
}
You could use the reference to implementation idiom in your class.
public class DesignerHappy
{
private ADesignerHappyImp imp_;
public int MyMethod()
{
return imp_.MyMethod()
}
public int MyProperty
{
get { return imp_.MyProperty; }
set { imp_.MyProperty = value; }
}
}
public abstract class ADesignerHappyImp
{
public abstract int MyMethod();
public int MyProperty {get; set;}
}
DesignerHappy just exposes the interface you want but forwards all the calls to the implementation object. You extend the behavior by sub-classing ADesignerHappyImp, which forces you to implement all the abstract members.
You can provide a default implementation of ADesignerHappyImp, which is used to initialize DesignerHappy by default and expose a property that allows you to change the implementation.
Note that "DesignMode" is not set in the constructor. It's set after VS parses the InitializeComponents() method.
I know its not quite what you are after but you could make all of your stubs in the base class throw the NotImplementedException. Then if any of your subclasses have not overridden them you would get a runtime exception when the method in the base class gets called.
The Component class contains a boolean property called "DesignMode" which is very handy when you want your code to behave differently in the designer than at runtime. May be of some use in this case.
As a general rule, if there's no way in a language to do something that generally means that there's a good conceptual reason not to do it.
Sometimes this will be the fault of the language designers - but not often. Usually I find they know more about language design than I do ;-)
In this case you want a un-overridden virtual method to throw a compile time exception (rather and a run time one). Basically an abstract method then.
Making virtual methods behave like abstract ones is just going to create a world of confusion for you further down the line.
On the other hand, VS plug in design is often not quite at the same level (that's a little unfair, but certainly less rigour is applied than is at the language design stage - and rightly so). Some VS tools, like the class designer and current WPF editors, are nice ideas but not really complete - yet.
In the case that you're describing I think you have an argument not to use the class designer, not an argument to hack your code.
At some point (maybe in the next VS) they'll tidy up how the class designer deals with abstract classes, and then you'll have a hack with no idea why it was coded that way.
It should always be the last resort to hack your code to fit the designer, and when you do try to keep hacks minimal. I find that it's usually better to have concise, readable code that makes sense quickly over Byzantine code that works in the current broken tools.
To use ms as an example...
Microsoft does this with the user control templates in silverlight. #if is perfectly acceptable and it is doubtful the the tooling will work around it anytime soon. IMHO
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
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)
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.
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 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.
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.
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.
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)
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();
}
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.
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.
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.
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
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!
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.
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.
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??
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.
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.