【问题标题】:C# Extension methods and protection level?C#扩展方法和保护级别?
【发布时间】:2015-04-30 10:38:35
【问题描述】:

我正在尝试为 MVC 控制器类编写扩展方法,因为我在程序中反复看到这样的代码:

if (viewModel == null)
{
    return HttpNotFound();
}
return View(viewModel);

我的想法是我想要一个名为ViewModelResult() 的扩展方法来处理这个问题,以便它根据视图模型是否可用返回ActionResultHttpNotFound 结果。这样,我就不用每次都写这 3-4 行代码了。

但是,MVC 控制器中的方法View()HttpNotFound() 的保护级别似乎造成了一些严重的问题。我已经编写了如下代码,但它不起作用:

public static class ExtensionController
{
    public static ActionResult ViewModelResult(this Controller controller, ViewModel viewModel)
    {
        if (viewModel == null)
        {
            return controller.HttpNotFound();
        }
        return controller.View(viewModel);
    }
}

它会抛出错误消息,例如“System.Web.MVC.Controller.View() 由于其保护级别而无法访问”。这让我很困惑,我认为在扩展方法中,this 关键字标记的对象的所有私有和受保护方法都是可访问的,就像在这个类中编写方法一样。但事实证明我错了,那些非公共方法在扩展方法中是不可访问的。

现在的问题是,我该如何解决这个问题?我有点不知所措,不知道我能做些什么。 MVC 控制器类来自 .NET 框架,我无法修改源代码。无论如何都不建议更改 .NET 框架的内部实现。任何人都可以帮忙吗?在这种情况下,你建议我做什么?

【问题讨论】:

    标签: c# asp.net asp.net-mvc controller asp.net-mvc-5


    【解决方案1】:

    您可以创建Controller 类的子类并向其添加方法。

    public abstract class ControllerBase : Controller
    {
        protected ActionResult ViewModelResult(ViewModel viewModel)
        {
            if (viewModel == null)
            {
                return HttpNotFound();
            }
            return View(viewModel);
        }
    }
    
    public class ValuesController : ControllerBase
    {
        public ActionResult Index()
        {
            var vm = ...;
            return ViewModelResult(vm);
        }
    }
    

    【讨论】:

      【解决方案2】:

      只是为了完成@Markus的答案: 正如您在 MSDN Controller.View Method 上看到的那样,您只能通过继承访问 View 方法

      扩展方法是纯粹的语法糖,在编译时被你的ExtensionController.ViewModelResult(this,viewModel);替换

      因此,如果您的扩展类不是您要扩展的对象的库的一部分,则您只能访问公共修饰符。

      【讨论】:

        猜你喜欢
        • 2013-02-26
        • 1970-01-01
        • 1970-01-01
        • 2021-07-02
        • 1970-01-01
        • 2021-12-05
        • 1970-01-01
        • 2010-12-03
        • 1970-01-01
        相关资源
        最近更新 更多