获取扩展方法的MethodInfo

时间:2009-06-12 16:48:15

标签: c# reflection extension-methods

我无法获得扩展方法的方法信息,因为我怀疑。怎么了?

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

4 个答案:

答案 0 :(得分:5)

适合我:

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
            ("TryToString", BindingFlags.Public | BindingFlags.Static);
        // Prints System.String TryToString(System.Object)
        Console.WriteLine(method);
    }
}

你能否给出一个类似的简短而完整的例子,但是失败了?

答案 1 :(得分:2)

适合我。只需检查您的方法类,名称和修饰符都是正确的。

作为一个说明,没有理由在任何情况下它都不应该起作用。扩展方法仍然是“正常”方法,因为它们属于定义的静态类。它只是你访问它们的方式不同(当然你也可以正常访问它们)。

答案 2 :(得分:0)

我也无法在我的代码上获得扩展方法 这只是我的命名空间冲突,而不是我的Extension类 它使用的是EntityFramework的Extension类,因此我必须明确键入它

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

而不是:

typeof(Extensions).GetMethod(...)

答案 3 :(得分:0)

对于那些不想在 Extension 类上调用 GetMethod 的人,目前只有一种方法。您应该获取命名空间中所有具有 ExtensionAttribute 的类型(该属性在编译时自动赋予扩展类和方法。)

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

然后我们将获得具有 ExtensionAttribute 的方法。

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

因此,extensionMethods 的结果将是命名空间中的所有扩展方法。我们只需要它们的第一个参数是我们选择的类型。

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

现在您拥有了一个包含所选类型的所有扩展方法的数组,您可以通过名称找到正确的方法。
完整代码:

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);

请注意,我们使用 null 作为对象进行调用,因为该方法是静态的。