我有一个扩展方法:
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);
答案 0 :(得分:7)
使用此扩展方法获取其他扩展方法:
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)});
答案 1 :(得分:1)
您应该使用BindingAttr参数使用 GetMethod 的另一个重载:
Type extendedType = typeof(StringEx);
MethodInfo myMethodInfo = extendedType.GetMethod("Like", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic , null, new[] {typeof(string), typeof(string)},null);
答案 2 :(得分:1)
假设您具有扩展方法:
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);
已测试;)...
答案 3 :(得分:0)
您可以像使用任何静态方法一样访问此方法:
var like = typeof(StringEx).GetMethod("Like", new[] { typeof(string), typeof(string) });