[英]invoke the extension method of a class without using static class but by using class iteslf using reflection
我想調用Method2,這是使用MyClass類型的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();
}
}
}
實際上,有一種解決方法,但這有點困難。 如果您不忘記在擴展方法參數中放置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)
或任何其他過濾器過濾所有類型,它仍然非常慢 。 如果您有其他方法可以調用擴展方法中的代碼,則可能應該使用該方法。
當然它的可能,唯一需要注意的是NET反射不理解的擴展方法的語法糖this
。
記住,擴展方法是一種C#構造,可以在給定第一個參數(標有this
關鍵字)的情況下調用static類static方法時為您節省幾個可打印字符。
因此,在短時間內,您必須以靜態類為目標,並將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
的成員,您不能以我能想到的任何方式強迫它是這樣的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.