简体   繁体   English

获取扩展方法的 MethodInfo

[英]Get MethodInfo for Extension Method

I cant get the method info for an extension method as I would suspect.我无法像我怀疑的那样获取扩展方法的方法信息。 Whats wrong?怎么了?

_toStringMethod = typeof(ObjectExtensions).GetMethod("TryToString",
    BindingFlags.Public | BindingFlags.Static);

Works for me:对我有用:

using System;
using System.Reflection;

public static class ObjectExtensions
{
    public static string TryToString(this object x)
    {
        // Just guessing...
        return x == null ? "" : x.ToString();
    }
}

class Test
{
    static void Main()
    {
        var method = typeof(ObjectExtensions).GetMethod(
            nameof(ObjectExtensions.TryToString),
            BindingFlags.Public | BindingFlags.Static);
        // Prints System.String TryToString(System.Object)
        Console.WriteLine(method);
    }
}

Can you give a similar short but complete example which fails?你能举一个类似的简短但完整的例子吗?

Works for me.为我工作。 Just check that your method class, name, and modifier are all correct.只需检查您的方法类、名称和修饰符是否全部正确。

As a note, there is no reason that it shouldn't work under any circumstances.请注意,没有理由认为它在任何情况下都不起作用。 Extension methods are still "normal" methods in that they belong to the static class in which the defined.扩展方法仍然是“普通”方法,因为它们属于定义的静态类。 It is only the way you access them that differs (though you can still access them normally too, of course).只是您访问它们的方式不同(当然,您仍然可以正常访问它们)。

I was unable to get the extension method on my code too It was just a namespace conflict of me which instead of my Extension class It was using EntityFramework's Extension class so I have to explicitly type it我也无法在我的代码中获取扩展方法 这只是我的命名空间冲突,而不是我的扩展类 它使用的是 EntityFramework 的扩展类,所以我必须明确键入它

typeof(MyAppNamespace.Extensions).GetMethod(...)

instead of:代替:

typeof(Extensions).GetMethod(...)

For those who don't want to call GetMethod on the Extension class, there is only one way at the moment.对于那些不想在 Extension 类上调用GetMethod的人,目前只有一种方法。 You should get all the Types in the namespace which have ExtensionAttribute (This attribute is given to extension classes and methods in compile time automatically.)您应该获取命名空间中具有ExtensionAttribute所有类型(该属性在编译时自动赋予扩展类和方法。)

Type[] allTypes = Assembly.GetEntryAssembly().GetTypes();
Type[] extensionTypes = allTypes.Where(t => t.IsDefined(typeof(ExtensionAttribute))).ToArray();

Then we'll get the methods which have ExtensionAttribute .然后我们将获得具有ExtensionAttribute的方法。

MethodInfo[] extensionMethods = extensionTypes.SelectMany(e => e.GetMethods().Where(m => m.IsDefined(typeof(ExtensionAttribute)))).ToArray();

So, the result of extensionMethods will be all the extension methods in the namespace.因此, extensionMethods的结果将是命名空间中的所有扩展方法。 We only need the ones that their first parameter is of our selected type.我们只需要它们的第一个参数是我们选择的类型。

MethodInfo[] matchExtensionMethods = extensionMethods.Where(m => m.GetParameters()[0].ParameterType == typeof(MyType)).ToArray();

Now you have an array of all the extension methods for your chosen type, you can find the proper method by its name.现在您拥有了一个包含所选类型的所有扩展方法的数组,您可以通过名称找到正确的方法。
Full code:完整代码:

Type targetType = typeof(MyClass);
MyClass targetObject = new MyClass();
Type[] allTypes = Assembly.GetEntryAssembly().GetTypes();
Type[] extensionTypes = allTypes.Where(t => t.IsDefined(typeof(ExtensionAttribute))).ToArray();
MethodInfo[] extensionMethods = extensionTypes.SelectMany(e => e.GetMethods().Where(m => m.IsDefined(typeof(ExtensionAttribute)))).ToArray();
MethodInfo[] matchExtensionMethods = extensionMethods.Where(m => m.GetParameters()[0].ParameterType == targetType).ToArray();
matchExtensionMethods.First(m => m.Name == "TryToString").Invoke(null, targetObject);

Please note that we're invoking with null passed as the object, because the method is static.请注意,我们使用 null 作为对象进行调用,因为该方法是静态的。

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

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