如何获取“string”类型的所有方法,使用所有扩展方法,如“聚合”,“选择”和其他c#反射?我知道类型大多数实现接口IEnumerable<>,但所有这些扩展方法在Enumerable类中具有第一个通用参数TSource.Ok ...代码:
var type = typeof(string).GetMethods(); //i get all methods string type
//I want get for this type all extensions methods like "Select" "Where"
//so i get all interfaces
type.GetInterfaces();
//ICompareble
//ICloneable
//...
//IEnumearable, but all this interfaces don't have extensions methods
//They locate in Enumerable class
//how i can use string type go to Enumerable class and get all this methods
//Somthigs like this
typeof(Enumerable).GetMethods(); //i want get all this methods but using type "string"
//Aggregate
//Select
//where
答案 0 :(得分:1)
扩展方法当然可以在不同的程序集中定义,因此第一个问题是我们关心的程序集。我们将从
开始var assemblies = GetType().Assembly
.GetReferencedAssemblies()
.Select(an => Assembly.Load(an))
.Concat(Enumerable.Repeat(GetType().Assembly, 1));
to(在实例方法或属性的上下文中)获取当前程序集及其引用的所有内容,因为这是可用的扩展方法的可行来源。其他用途将有其他起点。
现在我们需要获得所有扩展方法:
var availableExtensionMethods = assemblies
// First get all the types
.SelectMany(asse => asse.GetExportedTypes())
// Cut out some which cannot be static classes first
.Where(t => t.IsAbstract && t.IsSealed && t.GetConstructors().Length == 0)
// Get all their methods.
.SelectMany(t => t.GetMethods())
// Restrict to just the extension methods
.Where(m => m.GetCustomAttributes().Any(ca => ca is System.Runtime.CompilerServices.ExtensionAttribute)
// An extension method must have at least one parameter, but we'll rule out being
// messed up by some strangely defined method through weird direct use of
// the ExtensionAttribute attribute
&& m.GetParameters().Length != 0)
// Get an object with the method and the first parameter we'll use below.
.Select(m => new {Method = m, FirstParam = m.GetParameters()[0]});
现在,基类(string
)上直接用SomeMethod(this string arg)
(SomeMethod(this object arg)
)定义的那些将是:
var stringExtensions = availableExtensionMethods
.Where(info => info.FirstParam.ParameterType.IsAssignableFrom(typeof(string)))
.Select(info => info.Method);
上述内容包括(this IEnumerable<char> arg)
。要在泛型类型字符串实现上进行一般定义(例如(this IEnumerable<T> arg)
,我们将使用:
var stringGenericInterfaces = typeof(string).GetInterfaces()
.Where(i => i.IsGenericType)
.Select(i => i.GetGenericTypeDefinition());
var extensionsOnGenericInterfaces = from info in
availableExtensionMethods.Where(aem => aem.FirstParam.ParameterType.ContainsGenericParameters)
from inter in stringGenericInterfaces
where info.FirstParam.ParameterType.GetGenericTypeDefinition().IsAssignableFrom(inter)
select info.Method;
然后你可以Union
这些来获得很多。
尽管如此,我还没有对限制进行检查。
答案 1 :(得分:0)
string的扩展方法位于Enumerable类和IEnumerable接口中,它们位于mscorlib程序集的System.Linq命名空间中。 您可以通过以下方式获取System.Linq中扩展方法的名称:
//The actual method to find all extension methods in the assembly
//that take IEnumerable<TSource> or TSource as parameters.
public static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly,Type extendedType)
{
var query = from type in assembly.GetTypes()
where type == typeof(Enumerable)
from method in type.GetMethods(BindingFlags.Static
| BindingFlags.Public | BindingFlags.NonPublic)
where method.IsDefined(typeof(ExtensionAttribute), false)
where (method.GetParameters()[0].ParameterType.IsGenericType
| (method.GetParameters()[0].ParameterType.ContainsGenericParameters)
select method;
return query;
}
//Get the assembly System.Linq
Assembly thisAssembly = Assembly.GetAssembly(typeof(Enumerable));
foreach (MethodInfo method in GetExtensionMethods(thisAssembly,
typeof(string)))
{
Console.WriteLine(method);
}