你如何为一般类型的类编写C#扩展方法

时间:2008-09-16 02:03:16

标签: c# asp.net-mvc generics extension-methods

这应该是一个简单的。

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

这种扩展方法应该如何看待?

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

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

解决方案

一般解决方案是this answer

扩展System.Web.Mvc.ViewPage类的具体解决方案是my answer,它来自general solution

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

7 个答案:

答案 0 :(得分:17)

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

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

答案 1 :(得分:5)

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

  

'TModel'类型必须是参考   键入以将其用作参数   泛型类型或方法中的“TModel”

指向this page,它产生了这个解决方案:

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

答案 2 :(得分:3)

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

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

编辑:错过了几秒钟!

答案 3 :(得分: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既是引用类型(类)又具有无参数构造

答案 4 :(得分:1)

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

类似......

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

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

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

答案 5 :(得分:1)

Glenn Block有一个向ForEach实施IEnumerable<T>扩展方法的好例子。

来自他的blog post

public static class IEnumerableUtils
{
    public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
    {
        foreach(T item in collection)
            action(item);
    }
}

答案 6 :(得分: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();
    }
}

你真的不需要使用Generic版本,因为泛型版本扩展了非泛型版本,所以只需将它放在非泛型基类中就完成了:)