Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encapsulation issue with delegates?

I'm wondering why this works?

For example I have some executor class that looks like so:

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

Now I have some need to be executed class that looks like:

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's I pass a private method to other class?

Is this not an encapsulation issue?

like image 788
hackp0int Avatar asked Dec 12 '22 16:12

hackp0int


2 Answers

No, this is not a violation of encapsulation.

First off: the class itself is the thing that decided to hand out a delegate to one of its private methods! The class has access to its private methods and if it chooses to hand a reference to one to code outside of the accessibility domain of that method, that's perfectly within its rights.

Second: the accessibility domain of a method doesn't restrict where the method can be called. It restricts where the method can be looked up by name. Class Executor is never using the name DoSomething to invoke the private method. It's using the name action.

like image 115
Eric Lippert Avatar answered Dec 14 '22 07:12

Eric Lippert


Let me give it a try then.

No we don't have an encapsulation issue. You are defining a class that is responsible to Execute something. The Executer knows nothing about what actually is executed. It only knows that it should execute DoSomething. What DoSomething does is specified in the class that is responsible to have something executed.

As I commented, it's quite similar to what you would do with a Thread. You define a method that needs to be executed on a different Thread. That's why the class has a Thread, and defines which method should be ran on that Thread. Thread still knows nothing about the class where it plays a role in.

The relations are Class => Thread. Not the other way around.

In your example, the relations are NeedToBeExecuted => Executer. Not the other way around.

The concept can be tricky to your mind, but you are doing nothing wrong.

like image 34
bas Avatar answered Dec 14 '22 06:12

bas