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

这应该是一个简单的。

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

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

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

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

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

扩展System.Web.Mvc.ViewPage类的具体解决方案是我的答案 ,从一般解决方案开始。

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

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

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

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

类型’TModel’必须是引用类型才能在generics类型或方法中将其用作参数’TModel’

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

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

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

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

编辑:几秒钟就错过了!

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

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

Glenn Block有一个向IEnumerable实现ForEach扩展方法的好例子。

从他的博客文章 :

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

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

就像是…

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

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

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

以下是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版本,因为generics版本扩展了非generics版本,所以只需将它放在非generics基类中,你就完成了:)