I want invoke Method2 which is an extension method of a MyClass using MyClass type. I am wondering if this is possible or not.
using System;
using System.Linq;
using System.Reflection;
namespace ConsoleApplication9
{
public static class MyClassStatic
{
public static void Method2(this ConsoleApp2.MyClass obj)
{
Console.WriteLine("You have called ex Method 2");
}
}
public interface IClass
{
void Method1();
}
public class MyClass : ConsoleApp2.IClass
{
public void Method1()
{
Console.WriteLine("You have called Method 1");
}
}
class Program
{
public static void CallWhereMethod()
{
var whereMethods = typeof(MyClass)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(mi => mi.Name == "Method2");
Console.WriteLine(whereMethods.Count());
// returns zero
}
static void Main(string[] args)
{
CallWhereMethod();
Console.ReadKey();
}
}
}
Actually, there is a way for this, but it's hard a bit. If you don't forget to place a this
keyword to your extension method parameter, C# compiler will emmit ExtensionAttribute to this method and this class. Knowing this, you are able to find this extension method and execute it:
var myClassType = typeof(MyClass);
var myClass = new MyClass();
var assemblyTypes = Assembly.GetExecutingAssembly().GetTypes();
foreach (var type in assemblyTypes.Where(t => t.GetCustomAttribute<ExtensionAttribute>() != null)
{
var typeMethods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var method in typeMethods.Where(m => m.IsDefined(typeof(ExtensionAttribute), inherit: false))
{
if (method.GetParameters()[0].ParameterType == myClassType)
{
// here you go
method.Invoke(null, new object[]{ myClass });
}
}
}
If you unsure in which assembly to search for extension method, you may try to search all:
var allLoadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes());
Please note: reflection is slow. Really slow. Even you filter all of your types with .Where(type => type.IsSealed)
or any other filter, it is still dead slow. If you have any other way to invoke the code in your extension method, you probably should use that way.