特定の拡張メソッドが存在するかを調べる


2ちゃんねるのふらっとC#,C♯,C#(初心者用) Part78 の >>312 から。正直質問者の意図をつかめないので,勝手に以下のように問題を定義して考えてみました。

問題

ある MethodInfo が与えられたとき,そのメソッドが特定のクラスの拡張メソッドであるかどうかを判定せよ。

解答例

リフレクションを使って拡張メソッドを列挙し,その中に与えられた MethodInfo が含まれるかを判定します。

public static bool IsExtensionMethod(this MethodInfo method, Type type)
{
   if (type == null)
   {
      throw new ArgumentNullException("type");
   }
   if (method == null)
   {
      throw new ArgumentNullException("method");
   }
   return type.GetExtensionMethods(method.DeclaringType).Contains(method);
}

private static IEnumerable<MethodInfo> GetExtensionMethods(this Type type, Type extensionType)
{
   return from method in extensionType.GetMethods(BindingFlags.Public | BindingFlags.Static)
          where method.IsDefined(typeof(ExtensionAttribute), false)
          let parameters = method.GetParameters()
          where parameters.Length > 0
          let parameterType = parameters[0].ParameterType
          where parameterType == type || parameterType.IsSubclassOf(type)
          select method;
}

使用例

public class Bar
{
   public void InstanceMethod() {}
}
public static class BarExtension
{
   public static void ExtensionMethod(this Bar bar) {}
}

class Program
{
   private delegate void Hoge();

   static void Main()
   {
      Bar bar = new Bar();
      Console.WriteLine(new Hoge(bar.InstanceMethod).Method.IsExtensionMethod(typeof(Bar)));  // False
      Console.WriteLine(new Hoge(bar.ExtensionMethod).Method.IsExtensionMethod(typeof(Bar)));  // True
   }
}