如何使用 GetMethod 进行静态扩展方法

发布于 2024-12-19 02:43:58 字数 409 浏览 2 评论 0原文

我有一个扩展方法:

public static class StringEx
{
    public static bool Like(this string a, string b)
    {
        return a.ToLower().Contains(b.ToLower());
    }
}

如何通过 GetMethod 使用我的参数正确反映它?我尝试过但没有成功(关于静态方法有一个例外):

var like = typeof(StringEx).GetMethod("Like", new[] {typeof(string), typeof(string)});
comparer = Expression.Call(prop, like, value);

I've got an extension method:

public static class StringEx
{
    public static bool Like(this string a, string b)
    {
        return a.ToLower().Contains(b.ToLower());
    }
}

How to reflect it properly via GetMethod with my parameters? I've tried this with no success (Got an exception about static method):

var like = typeof(StringEx).GetMethod("Like", new[] {typeof(string), typeof(string)});
comparer = Expression.Call(prop, like, value);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

站稳脚跟 2024-12-26 02:43:58

使用此扩展方法来获取其他扩展方法:

public static class ReflectionExtensions
{   
    public static IEnumerable<MethodInfo> GetExtensionMethods(this Type type, Assembly extensionsAssembly)
    {
        var query = from t in extensionsAssembly.GetTypes()
                    where !t.IsGenericType && !t.IsNested
                    from m in t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                    where m.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false)
                    where m.GetParameters()[0].ParameterType == type
                    select m;

        return query;
    }

    public static MethodInfo GetExtensionMethod(this Type type, Assembly extensionsAssembly, string name)
    {
        return type.GetExtensionMethods(extensionsAssembly).FirstOrDefault(m => m.Name == name);
    }

    public static MethodInfo GetExtensionMethod(this Type type, Assembly extensionsAssembly, string name, Type[] types)
    {
        var methods = (from m in type.GetExtensionMethods(extensionsAssembly)
                       where m.Name == name
                       && m.GetParameters().Count() == types.Length + 1 // + 1 because extension method parameter (this)
                       select m).ToList();

        if (!methods.Any())
        {
            return default(MethodInfo);
        }

        if (methods.Count() == 1)
        {
            return methods.First();
        }

        foreach (var methodInfo in methods)
        {
            var parameters = methodInfo.GetParameters();

            bool found = true;
            for (byte b = 0; b < types.Length; b++)
            {
                found = true;
                if (parameters[b].GetType() != types[b])
                {
                    found = false;
                }
            }

            if (found)
            {
                return methodInfo;
            }
        }

        return default(MethodInfo);
    }
}

像这样使用它:

var assembly = Assembly.GetExecutingAssembly(); //change this to whatever assembly the extension method is in

var methodInfo = typeof(string).GetExtensionMethod(assembly,"Like",new[] { typeof(string)});

Use this extension method to get other extension methods:

public static class ReflectionExtensions
{   
    public static IEnumerable<MethodInfo> GetExtensionMethods(this Type type, Assembly extensionsAssembly)
    {
        var query = from t in extensionsAssembly.GetTypes()
                    where !t.IsGenericType && !t.IsNested
                    from m in t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                    where m.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false)
                    where m.GetParameters()[0].ParameterType == type
                    select m;

        return query;
    }

    public static MethodInfo GetExtensionMethod(this Type type, Assembly extensionsAssembly, string name)
    {
        return type.GetExtensionMethods(extensionsAssembly).FirstOrDefault(m => m.Name == name);
    }

    public static MethodInfo GetExtensionMethod(this Type type, Assembly extensionsAssembly, string name, Type[] types)
    {
        var methods = (from m in type.GetExtensionMethods(extensionsAssembly)
                       where m.Name == name
                       && m.GetParameters().Count() == types.Length + 1 // + 1 because extension method parameter (this)
                       select m).ToList();

        if (!methods.Any())
        {
            return default(MethodInfo);
        }

        if (methods.Count() == 1)
        {
            return methods.First();
        }

        foreach (var methodInfo in methods)
        {
            var parameters = methodInfo.GetParameters();

            bool found = true;
            for (byte b = 0; b < types.Length; b++)
            {
                found = true;
                if (parameters[b].GetType() != types[b])
                {
                    found = false;
                }
            }

            if (found)
            {
                return methodInfo;
            }
        }

        return default(MethodInfo);
    }
}

Use it like this:

var assembly = Assembly.GetExecutingAssembly(); //change this to whatever assembly the extension method is in

var methodInfo = typeof(string).GetExtensionMethod(assembly,"Like",new[] { typeof(string)});
梦过后 2024-12-26 02:43:58

您应该使用带有 BindingAttr 参数的 GetMethod 的另一个重载:

Type extendedType = typeof(StringEx);
MethodInfo myMethodInfo = extendedType.GetMethod("Like", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic , null, new[] {typeof(string), typeof(string)},null);

You should use another overload of GetMethod with BindingAttr parameter:

Type extendedType = typeof(StringEx);
MethodInfo myMethodInfo = extendedType.GetMethod("Like", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic , null, new[] {typeof(string), typeof(string)},null);
彼岸花似海 2024-12-26 02:43:58

假设你有一个扩展方法:

public static class StringEx
{
    public static bool Like(this string a, string b)
    {
        return a.ToLower().Contains(b.ToLower());
    }
}

你需要这样的东西:

string value = "Something";
ParameterExpression Param = Expression.Parameter(typeof(T), "x");
MemberExpression Member = Expression.Property(Param, "PropertyName");
MethodInfo ToStringMethod = typeof(object).GetMethod("ToString");
MethodInfo ComparerMethod = typeof(StringEx).GetMethod("Like", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new[] { typeof(string), typeof(string) }, null);
MethodCallExpression ToStringExpression = Expression.Call(Member, ToStringMethod);
MethodCallExpression ComparerExpression = Expression.Call(ComparerMethod, ToStringExpression, Expression.Constant(value));
    // Here is what you need
Expression<Func<T, bool>> CustomLamdaResult = Expression.Lambda<Func<T, bool>>(body: ComparerExpression , parameters: Param);

已测试;)...

Assuming you've an extension method:

public static class StringEx
{
    public static bool Like(this string a, string b)
    {
        return a.ToLower().Contains(b.ToLower());
    }
}

You need something like this:

string value = "Something";
ParameterExpression Param = Expression.Parameter(typeof(T), "x");
MemberExpression Member = Expression.Property(Param, "PropertyName");
MethodInfo ToStringMethod = typeof(object).GetMethod("ToString");
MethodInfo ComparerMethod = typeof(StringEx).GetMethod("Like", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new[] { typeof(string), typeof(string) }, null);
MethodCallExpression ToStringExpression = Expression.Call(Member, ToStringMethod);
MethodCallExpression ComparerExpression = Expression.Call(ComparerMethod, ToStringExpression, Expression.Constant(value));
    // Here is what you need
Expression<Func<T, bool>> CustomLamdaResult = Expression.Lambda<Func<T, bool>>(body: ComparerExpression , parameters: Param);

Tested ;)...

北渚 2024-12-26 02:43:58

您可以像访问任何静态方法一样访问此方法:

var like = typeof(StringEx).GetMethod("Like", new[] { typeof(string), typeof(string) });

You could to access this method as you would do with any static method:

var like = typeof(StringEx).GetMethod("Like", new[] { typeof(string), typeof(string) });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文