简体   繁体   English

在不使用静态类的情况下调用类的扩展方法,而是通过使用反射使用类iteslf

[英]invoke the extension method of a class without using static class but by using class iteslf using reflection

I want invoke Method2 which is an extension method of a MyClass using MyClass type. 我想调用Method2,这是使用MyClass类型的MyClass的扩展方法。 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. 如果您不忘记在扩展方法参数中放置this关键字,则C#编译器会将ExtensionAttribute赋予该方法和此类。 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 . 即使您使用.Where(type => type.IsSealed)或任何其他过滤器过滤所有类型,它仍然非常 If you have any other way to invoke the code in your extension method, you probably should use that way. 如果您有其他方法可以调用扩展方法中的代码,则可能应该使用该方法。

Sure its possible, the only caveat is .Net Reflection doesn't understand the Extension Method syntactic-sugar of this . 当然它的可能,唯一需要注意的是NET反射不理解的扩展方法的语法糖this

Remembering, that an extension method is a C# construct to save you a couple of printable-characters when calling a static class static method when given the first parameter (labelled with the this keyword) 记住,扩展方法是一种C#构造,可以在给定第一个参数(标有this关键字)的情况下调用static类static方法时为您节省几个可打印字符。

So in-Short, you'll have to target the static class and pass in the MyClass instance as the first parameter 因此,在短时间内,您必须以静态类为目标,并将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 } );

Output 输出量

You have called ex Method 2

Full Demo Here 完整演示在这里

Update 更新资料

I dont want to use typeof(MyClassStatic).. I want to use typeof(MyClass) 我不想使用typeof(MyClassStatic)..我不想使用typeof(MyClass)

Method2 is not a member of MyClass , and you cant force it to be as such in any way that i can think of. Method2不是MyClass的成员,您不能以我能想到的任何方式强迫它是这样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM