如何通过扩展方法在不实例化的情况下使用对象?

时间:2013-12-29 01:53:32

标签: c#

我正在关注ASP.NET MVC一书。这是单元测试之一:

    [TestMethod]
    public void Can_Generate_Page_Links()
    {
        // arrange
        HtmlHelper myHelper = null;

        PagingInfo pagingInfo = new PagingInfo
        {
            CurrentPage = 2,
            TotalItems = 28,
            ItemsPerPage = 10
        };
        Func<int, string> pageUrlDelegate = i => "Page" + i;

        // act 
        MvcHtmlString result = myHelper.PageLinks(pagingInfo, pageUrlDelegate);

        // assert
        Assert.AreEqual(result.ToString(), 
            @"<a href=""Page1"">1</a>" + 
            @"<a href=""Page2"">2</a>" +
            @"<a href=""Page3"">3</a>"
        );
    }

注意myHelper如何设置为null然后使用?对HtmlHelper执行任何操作的唯一代码是此扩展方法:

    public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int, string> pageUrl)
    {
        StringBuilder result = new StringBuilder();
        for (int i = 1; i <= pagingInfo.TotalPages; i++)
        {
            TagBuilder tag = new TagBuilder("a");
            tag.MergeAttribute("href", pageUrl(i));
            tag.InnerHtml = i.ToString();
            if (i == pagingInfo.CurrentPage)
                tag.AddCssClass("selected");
            result.Append(tag.ToString());
        }

        return MvcHtmlString.Create(result.ToString());
    }

扩展方法是否与允许我们使用设置为null的对象有关?如果没有,这里发生了什么?

1 个答案:

答案 0 :(得分:3)

你是对的。

仅因为扩展方法是语法糖。编译时,它本质上是这样的调用:

YourStaticClass.PageLinks(myHelper, pagingInfo, pageUrlDelegate);

请注意,在PageLinks方法中,永远不会使用html参数。如果是,则会抛出NullReferenceException