我想使用MyClass类型调用Method2,它是MyClass的扩展方法。我想知道这是否可能。
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();
}
}
}
答案 0 :(得分:3)
实际上,有一种解决方法,但是有点困难。如果您不忘记在扩展方法参数中放置一个this
关键字,C#编译器将向该方法和此类发出ExtensionAttribute。知道了这一点,您便可以找到此扩展方法并执行它:
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 });
}
}
}
如果不确定在哪个程序集中搜索扩展方法,则可以尝试搜索全部:
var allLoadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes());
请注意:反射速度慢。真的很慢即使您使用.Where(type => type.IsSealed)
或其他任何过滤器过滤了所有类型,它仍然非常慢。如果您还有其他方法可以在扩展方法中调用代码,则可能应该使用该方法。
答案 1 :(得分:1)
当然,唯一的警告是。NetReflection 无法理解this
的扩展方法语法糖。
请记住,扩展方法是一种C#构造,当在给定第一个参数(标有this
关键字)的情况下调用静态类static方法时,可以为您节省几个可打印字符 em>
因此,在短期内,您必须定位静态类,并将MyClass
实例作为第一个参数传递
var myClass = new MyClass();
var whereMethods = typeof(MyClassStatic)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.FirstOrDefault(mi => mi.Name == "Method2");
whereMethods.Invoke(null, new object[]{ myClass } );
输出
You have called ex Method 2
更新
我不想使用typeof(MyClassStatic)..我想使用 typeof(MyClass)
Method2
不是MyClass
的成员,并且您不能以我能想到的任何方式强迫它是如此。