.netで面白い「拡張方法」(Extension Method)
6885 ワード
ASPを見ています.NetMVCコードのとき、こんな呼び出しがありました.
ここでroutesはRouteCollectionクラスであり、RouteCollectionクラスにはMapRouteメソッドは存在しない.MapRouteメソッドはRouteCollectionExtensionsクラスのメソッドであり、メタデータから取得したRouteCollectionExtensionsの説明は以下の通りである.
このクラスは表面的には独立したクラスであり、他のクラスから継承されたものではなく、Interfaceも実現されていませんが、注意してください.まずstaticクラスであり、その方法もstatic である.実際には、そのメソッドの最初のパラメータは「this RouteCollection」であり、タイプの前に「this」 が追加されています.
これは何を表していますか.実はこれです.Netの面白い使い方です.それはクラスを拡張する方法ですが、このクラスのコードを直接修正しないで、次の簡単な例があります.
「AppendWorld」という方法は「Hello」というクラスに属しているように見えます.
これには、クラスのパッケージを破ることはできません.拡張方法は、拡張するクラスのpublicメンバーにアクセスするしかありません.他のメンバーは動けません.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
ここでroutesはRouteCollectionクラスであり、RouteCollectionクラスにはMapRouteメソッドは存在しない.MapRouteメソッドはRouteCollectionExtensionsクラスのメソッドであり、メタデータから取得したRouteCollectionExtensionsの説明は以下の通りである.
public static class RouteCollectionExtensions
{
public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, RouteValueDictionary values);
public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values);
public static void IgnoreRoute(this RouteCollection routes, string url);
public static void IgnoreRoute(this RouteCollection routes, string url, object constraints);
public static Route MapRoute(this RouteCollection routes, string name, string url);
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults);
public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces);
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints);
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces);
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces);
}
このクラスは表面的には独立したクラスであり、他のクラスから継承されたものではなく、Interfaceも実現されていませんが、注意してください.
これは何を表していますか.実はこれです.Netの面白い使い方です.それはクラスを拡張する方法ですが、このクラスのコードを直接修正しないで、次の簡単な例があります.
class Hello
{
private string m_strHello = "Hello";
public string String { get { return m_strHello; } set { m_strHello = value; } }
}
static class HelloExtensions
{
public static void AppendWorld(this Hello hello)
{
hello.String += " World";
}
}
class Program
{
static void Main(string[] args)
{
Hello hello = new Hello();
hello.AppendWorld();
Console.WriteLine(hello.String);
}
}
「AppendWorld」という方法は「Hello」というクラスに属しているように見えます.
これには、クラスのパッケージを破ることはできません.拡張方法は、拡張するクラスのpublicメンバーにアクセスするしかありません.他のメンバーは動けません.