c#の拡張メソッドについて

静的メソッドをインスタンスメソッドっぽく呼べるようにしてくれる。

public static class Ext{
 public static void Apple(this string val){
  System.Console.Write("Apple");
 }
}

上記のように書くことで string型のインスタンス

  "str".Apple()

のようにコールすることが出来る。

拡張メソッドAppleの引数にはレシーバのインスタンスの値渡しが入る。refは使用出来ず、型にdynamicを指定することも出来ない。

また静的メソッドをインスタンスメソッドのようにコール出来るようにしてるだけなので、静的メソッドの制約を受ける。

 拡張メソッドの引数にインターフェースを指定することで特定のインターフェースを継承したクラスにのみメソッドの使用(共有)を許すことが出来る。

namespace ForTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var ins = new MyClass();
            ins.Mt();
            Console.ReadLine();
        }
    }
}

public static class Ext {

    public static void Mt(this Itf mc)
    {
        System.Console.Write("OK");
    }
}

public interface Itf { }

public class MyClass : Itf { }

 

これでItfインターフェースを継承したクラスのみが、Mt()を使える。

なお、MyClassを継承したクラスはインターフェースも継承するのでMt()を使える。

拡張メソッドの引数の型にインターフェースを指定すると、使えるメソッドがインターフェースに宣言されたものに限定されるので、インターフェースを継承したクラスのインスタンス変数を拡張メソッド内で利用するにはそのインターフェースにアクセサとなるメソッドを宣言し、クラスで実装する必要がある。

 

++参考

c# - C#にRubyにおけるmoduleに相当する機能はありますか? - スタック・オーバーフロー

拡張メソッド - C# によるプログラミング入門 | ++C++; // 未確認飛行 C