扩展方法当然可以在不同的组件来定义,所以第一个问题是我们关心哪些程序集。我们将与
var assemblies = GetType().Assembly
.GetReferencedAssemblies()
.Select(an => Assembly.Load(an))
.Concat(Enumerable.Repeat(GetType().Assembly, 1));
到(在实例方法或属性的上下文中)获得当前的装配和所有它引用开始,因为这是对扩展方法可用那里,然后可行的来源。其他用途将有其他出发点。
现在我们需要把所有的扩展方法:
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]});
现在,那些直接在基类(SomeMethod(this object arg)
)的string
(SomeMethod(this string 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
这些结合在一起,以获得大量的
我没有列入约束检查这里虽然。
我认为你很容易发布一个可重现的代码,以便我们的机器可以在我们的机器上进行测试.. –
This link [link] http://stackoverflow.com/questions/299515/reflection- to-identify-extension-methods方法不起作用,因为他使用了第一个参数typeof(string),在我的版本中,这个方法具有第一个参数通用TSource。 – itihonov