Asp.net mvc 3 这段代码的意义是什么?

Asp.net mvc 3 这段代码的意义是什么?,asp.net-mvc-3,interface,implementation,Asp.net Mvc 3,Interface,Implementation,我正在阅读ASP.NET MVC3的源代码,在代码中我发现了以下内容: ControllerBase提供了执行的一个实现,但是它有一个定义IController.执行 为什么要这样做,它实现了什么?它似乎没有任何用途。根据,显式接口成员实现的一个目的是:由于显式接口成员实现无法通过类或结构实例访问,因此它们允许从类或结构的公共接口中排除接口实现。当类或结构实现了该类或结构的使用者不感兴趣的内部接口时,这尤其有用。” 如果我对上述内容的解释正确,则不能使用类型为ControllerBase的变量调

我正在阅读ASP.NET MVC3的源代码,在代码中我发现了以下内容:

ControllerBase提供了执行的一个实现,但是它有一个定义<代码>IController.执行

为什么要这样做,它实现了什么?它似乎没有任何用途。

根据,显式接口成员实现的一个目的是:由于显式接口成员实现无法通过类或结构实例访问,因此它们允许从类或结构的公共接口中排除接口实现。当类或结构实现了该类或结构的使用者不感兴趣的内部接口时,这尤其有用。”

如果我对上述内容的解释正确,则不能使用类型为
ControllerBase
的变量调用
Execute
,因为它受保护。变量的类型必须是
IController
。我不确定这是否是构造的意图,但感觉这就是原因


在相关测试中,在调用
Execute
之前,他们显式地将
ControllerBase
变量强制转换为
IController
,乍一看,这种设计模式似乎没有任何作用。然而,它确实为
ControllerBase
类提供了以后进行不间断更改的机会ts实现
IController
接口。更改将保证运行,因为它不依赖于调用
base.Execute()
的继承类。也许将来可以使用它来管理上下文或安全性


也许开发人员只是喜欢将接口与可重写的实现保持逻辑上的分离。

此代码使您可以重写Execute方法

请记住,通常实现的接口方法是公共的(不是虚拟的或抽象的),因此您不能在派生类中重写它,并且默认情况下,通过
IController
接口无法访问创建新的执行方法(如果没有此接口,则受保护的虚拟技术)。通过创建受保护的虚拟方法(从显式实现的接口方法调用),派生类可以重写Execute方法,而不会中断接口实现

我在这里找到了一篇关于这方面的优秀文章:

如果你覆盖了虚拟的
Execute
,那么显式的
IController.Execute
还会执行基本实现吗?@Joe否。它会执行一个被覆盖的虚拟执行,如果存在的话。因此,也许这只是一种黑客行为,让该方法
受到保护,而不是
public
。@Joe可能是。这就是vhallac建议,强制实行责任分离。是的。也许这只是一种从“外部”隐藏执行调用的奇特方式“@Scott我猜这是用来强制责任分离的。如果您持有一个
ControllerBase
引用,则不打算执行它。如果您持有一个
IController
,您只需要执行它。因此,本质上,如果我想通过接口公开一些功能,我想在子类中更改这些功能,我可以使用此模式。为什么您会喜欢此设计模式而不是
公共虚拟执行(RequestContext RequestContext)
?@Scott使用public virtual将允许从该类外部访问它,而无需引用IController接口。这将是公开的。使用protected将方法保留在ControllerBase类及其子类的内部,除非您有对IController接口的显式引用。因此,它有更好的保护,只有在非常有意访问时才使用。
public interface IController
{
    void Excecute(RequestContext requestContext);
}


public abstract class ControllerBase : IController
{

    protected virtual void Execute(RequestContext requestContext)
    {
        if (requestContext == null)
        {
            throw new ArgumentNullException("requestContext");
        }
        if (requestContext.HttpContext == null)
        {
            throw new ArgumentException(MvcResources.ControllerBase_CannotExecuteWithNullHttpContext, "requestContext");
        }

        VerifyExecuteCalledOnce();
        Initialize(requestContext);

        using (ScopeStorage.CreateTransientScope())
        {
            ExecuteCore();
        }
    }

    void IController.Execute(RequestContext requestContext)
    {
        Execute(requestContext);
    }
}