我想知道为什么会这样吗?
例如,我有一些执行者类,如下所示:
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
}
}
我的问题是为什么这是工作我将私有方法传递给其他类?
这不是封装问题吗?
答案 0 :(得分:6)
不,这不违反封装。
首先:类本身决定将委托分发给其私有方法之一!该类可以访问其私有方法,如果它选择将一个引用传递给该方法的可访问域之外的代码,则完全在其权限范围内。
第二:方法的可访问性域不限制方法可以的位置。 它限制了可以按名称查找方法的位置。类Executor
永远不会使用名称 DoSomething
来调用私有方法。它使用名称action
。
答案 1 :(得分:3)
让我试一试。
不,我们没有封装问题。您正在定义一个负责Execute
某事的类。 Executer
知道没有关于实际执行的内容。它只知道它应该执行DoSomething
。 DoSomething
在负责执行某些操作的类中指定了什么。
正如我评论的那样,它与你对Thread
所做的非常相似。您定义了一个需要在不同的Thread上执行的方法。这就是为什么类有一个Thread,并定义应该在该Thread上运行哪个方法。线程仍然对它所扮演角色的类一无所知。
关系是Class =>线。不是相反。
在您的示例中,关系为NeedToBeExecuted
=> Executer
。不是相反。
这个概念对你来说可能很棘手,但你没有做错任何事。
答案 2 :(得分:1)
与使用反射一样,这只是一个封装问题。使用反射可以非常轻松地从外部类访问私有方法和变量。你不应该认为这是一件坏事,因为它只会使语言变得更加强大。
该类是放弃委托方法的类,所以在某种程度上类正在启用行为,所以它根本不应该是封装问题。
答案 3 :(得分:1)
考虑一下:NeedToBeExecuted
没有公开DoSomething()
方法,因为它可以被任意调用 - 而是将它作为委托传递给另一个函数。它可以很容易地传递() => DoSomething()
- 结果是一样的。最终访问修饰符是为了防止使用您的方法的不同的类,您仍然可以随意使用它。如果你选择将它传递给另一个类,这是一个有效的用途。
答案 4 :(得分:1)
您在方法DoSomething
中传递了Invoke()
,并且可以在上下文中访问它。没有封装问题。
但是,当您在代码中看到评论时,DoSomething
无法访问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);
}
}
答案 5 :(得分:1)
封装意味着能够在不更改外部代码的情况下更改某些模块的内部。这仍然是这种情况。因此没有发生封装破坏。