4

我想知道为什么这有效?

例如,我有一些看起来像这样的执行器类:

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

现在我有一些需要执行的类,如下所示:

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

    private void DoSomething()
    {
        // do stuff private
    }
}

我的问题是为什么这是我将私有方法传递给其他类的工作?

这不是封装问题吗?

4

6 回答 6

6

不,这不违反封装。

首先:类本身决定将委托分发给它的一个私有方法!该类可以访问它的私有方法,并且如果它选择将一个引用交给该方法的可访问域之外的代码,那完全在它的权利范围内。

第二:方法的可访问域不限制可以调用方法的位置。 它限制了可以按名称查找方法的位置。类Executor从不使用名称 DoSomething来调用私有方法。它正在使用名称action

于 2013-03-23T14:27:23.733 回答
3

那我试一试吧。

不,我们没有封装问题。您正在定义一个对某事负责的类Execute。对实际执行的内容一无所知Executer。它只知道它应该执行。在负责执行某些操作的类中指定了什么。DoSomethingDoSomething

正如我评论的那样,它与您对Thread. 您定义了一个需要在不同线程上执行的方法。这就是为什么该类有一个线程,并定义应该在该线程上运行哪个方法。Thread 仍然对它所扮演角色的类一无所知。

关系是类 => 线程。不是反过来。

在您的示例中,关系是NeedToBeExecuted=> Executer。不是反过来。

这个概念对你来说可能很棘手,但你没有做错任何事。

于 2013-03-23T12:41:42.683 回答
1

它只是与使用反射一样多的封装问题。使用反射可以很容易地从外部类访问私有方法和变量。你不应该认为这是一件坏事,因为它只会让语言变得更加强大。

无论如何,该类是放弃委托方法的类,因此该类在某种程度上启用了该行为,因此它根本不应该是封装问题。

于 2013-03-23T12:42:46.480 回答
1

考虑一下:NeedToBeExecuted没有以DoSomething()可以任意调用的方式公开方法 - 而是将其作为委托传递给另一个函数。它也可以很容易地通过() => DoSomething()——结果是一样的。最终访问修饰符是为了防止使用您的方法的不同类,您仍然可以随意使用它。如果您选择将它传递给另一个类,这是一个有效的用途。

于 2013-03-23T12:51:09.227 回答
1

您传入DoSomethingmethod Invoke(),它可以在上下文中访问。不存在封装问题。

但是,正如您在代码中看到的注释,DoSomethingEitherNeedToBeExecuted.

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);
    }
}
于 2013-03-23T12:55:04.247 回答
1

封装意味着能够在不更改外部代码的情况下更改某些模块的内部结构。这里仍然是这种情况。所以没有发生封装破坏。

于 2013-03-23T12:55:31.853 回答