我们如何为通用类型的类编写C#扩展方法

时间:2020-03-05 18:55:00  来源:igfitidea点击:

希望这应该很简单。

我想向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类的特定解决方案是我下面的回答,该解决方案从常规解决方案开始。

区别在于,在特定情况下,我们既需要泛型方法声明,也需要一条语句来将泛型类型强制为引用类型。

解决方案

回答

我当前的计算机上未安装VS,但我认为语法为:

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

回答

它只需要函数的通用类型说明符即可:

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

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

回答

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

The type 'TModel' must be a reference
  type in order to use it as parameter
  'TModel' in the generic type or method

这使我指向此页面,从而产生了此解决方案:

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

回答

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

就像是...

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

注意,只有在我们声明具有匹配类型的ViewPage(在这种情况下)时,intellisense才会显示扩展方法。

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

回答

Glenn Block有一个很好的例子,可以对" IEnumerable <T>"实现" ForEach"扩展方法。

从他的博客文章中:

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

回答

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既是引用类型(类)又具有无参数的构造函数)。