你如何为一般类型的类编写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基类中,你就完成了:)