Question about encapsulation with delegates?

I wonder why this works?

For example, I have an artist class that looks like this:

public class Executor { public void Execute(Action action) { action(); } } 

Now I need to execute a class that looks like this:

 public class NeedToBeExecuted { public void Invoke() { Executor executor = new Executor(); executor.Execute(DoSomething); } private void DoSomething() { // do stuff private } } 

My question is why this is work. Am I passing a private method to another class ?

Isn't this an encapsulation problem?

+3
source share
6 answers

No, this is not a violation of encapsulation.

First of all: the class itself is what decided to pass the delegate to one of its private methods! A class has access to its private methods and, if it decides to pass a link to the code for code outside the accessibility domain of this method, which fully corresponds to its rights.

Secondly: the method availability area does not limit the method call method. It restricts the way a method is searched by name . The Executor class never uses the DoSomething name to invoke a private method. It uses the name action .

+6
source

Let me try.

No, we have no problem with encapsulation. You define a class that is responsible for Execute . Executer knows nothing about what is actually being executed. He only knows that he has to do DoSomething . What DoSomething does is indicated in the class responsible for doing something.

As I said, it is very similar to what you would do with Thread . You define a method that should be executed in another thread. Therefore, the class has a Thread and determines which method should be run in this thread. Thread still knows nothing about the class in which it plays a role.

Relations are class => Thread. Not the other way around.

In your example, the relationship NeedToBeExecuted => Executer . And not vice versa.

The concept may be complicated for your mind, but you are not doing anything wrong.

+3
source

This is just such an encapsulation problem as using reflection. One can easily access private methods and variables from an external class using reflection. You should not consider it bad, because it just makes the language stronger.

A class is one that rejects the delegation method anyway, so the class supports behavior, so it should not be an encapsulation problem at all.

+1
source

Consider this: NeedToBeExecuted does not expose the DoSomething() method in such a way that it can be called arbitrarily - instead, it passes it as a delegate to another function. It's just as easy to go through () => DoSomething() - the result will be the same. Ultimately, access modifiers prevent the use of another class using your method, you can still use it as you wish. If you decide to pass it to another class, this is a valid use.

+1
source

You pass DoSomething in the Invoke() method, and it is available in context. There is no encapsulation.

However, as you see the comment in the code, DoSomething not available in EitherNeedToBeExecuted .

 public class Executor { public void Execute(Action action) { action(); } } public class NeedToBeExecuted { public virtual void Invoke() { Executor executor=new Executor(); executor.Execute(this.DoSomething); } private void DoSomething() { Console.WriteLine("I'M DOING IT MYSELF!!"); } protected Executor m_Executor=new Executor(); } public class EitherNeedToBeExecuted: NeedToBeExecuted { public override void Invoke() { // 'NeedToBeExecuted.DoSomething()' is inaccessible due to its protection level m_Executor.Execute(base.DoSomething); } } 
+1
source

Encapsulation means the ability to change the internal elements of a module without changing the external code. This is still the case. Thus, no encapsulation violation occurred.

+1
source

Source: https://habr.com/ru/post/959099/


All Articles