11

这应该是一个简单的。

我想向 System.Web.Mvc.ViewPage< T > 类添加一个扩展方法。

这个扩展方法应该怎么看?

我的第一个直觉想法是这样的:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle(this ViewPage<Type> v)
        {
            return "";
        }
    }
}

解决方案

一般的解决方案是这个答案

扩展 System.Web.Mvc.ViewPage 类的具体解决方案是下面的回答,从通用解决方案开始。

不同之处在于,在特定情况下,您需要一个泛型类型的方法声明和一个将泛型类型强制为引用类型的语句。

4

7 回答 7

18

我当前的机器上没有安装 VS,但我认为语法是:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> v)
        {
            return "";
        }
    }
}
于 2008-09-16T02:05:58.580 回答
6

谢谢leddt。这样做会产生错误:

类型“TModel”必须是引用类型才能在泛型类型或方法中用作参数“TModel”

这指向了这个页面,它产生了这个解决方案:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> v) 
          where T : class
        {
            return "";
        }
    }
}
于 2008-09-16T02:10:13.750 回答
3

它只需要函数上的泛型类型说明符:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<Type>(this ViewPage<Type> v)
        {
            return "";
        }
    }
}

编辑:只是错过了几秒钟!

于 2008-09-16T02:06:55.940 回答
2
namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> view)
            where T : class
        {
            return "";
        }
    }
}

您可能还需要/希望将“new()”限定符添加到泛型类型(即“where T : class, new()”以强制 T 既是引用类型(类)又具有无参数构造函数。

于 2008-09-16T02:35:50.833 回答
1

如果您希望扩展仅适用于指定类型,您只需指定您将要处理的实际类型

就像是...

public static string GetDefaultPageTitle(this ViewPage<YourSpecificType> v)
{
  ...
}

请注意,智能感知将仅在您声明(在本例中)具有匹配类型的 ViewPage 时显示扩展方法。

另外,最好不要使用 System.Web.Mvc 命名空间,我知道不必在 usings 部分中包含命名空间会很方便,但如果为扩展函数创建自己的扩展命名空间,它更易于维护。

于 2008-09-16T02:15:24.737 回答
1

Glenn Block有一个很好的例子来ForEach实现IEnumerable<T>.

从他的博客文章

public static class IEnumerableUtils
{
    public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
    {
        foreach(T item in collection)
            action(item);
    }
}
于 2008-09-16T02:22:28.430 回答
1

这是 Razor 视图的示例:

public static class WebViewPageExtensions
{
    public static string GetFormActionUrl(this WebViewPage view)
    {
        return string.Format("/{0}/{1}/{2}", view.GetController(), view.GetAction(), view.GetId());
    }

    public static string GetController(this WebViewPage view)
    {
        return Get(view, "controller");
    }

    public static string GetAction(this WebViewPage view)
    {
        return Get(view, "action");
    }

    public static string GetId(this WebViewPage view)
    {
        return Get(view, "id");
    }

    private static string Get(WebViewPage view, string key)
    {
        return view.ViewContext.Controller.ValueProvider.GetValue(key).RawValue.ToString();
    }
}

您真的不需要使用通用版本,因为通用版本扩展了非通用版本,因此只需将其放在非通用基类中即可:)

于 2012-08-02T05:21:07.907 回答