在C#中有没有使用反射来判断一个方法是否作为扩展方法被添加到类中的技术?
给定如下所示的扩展方法,是否可以确定 Reverse() 已添加到字符串类中?
public static class StringExtensions
{
public static string Reverse(this string value)
{
char[] cArray = value.ToCharArray();
Array.Reverse(cArray);
return new string(cArray);
}
}
我们正在寻找一种机制来在单元测试中确定扩展方法是否由开发人员适本地添加。尝试这样做的一个原因是,开发人员可能会将类似的方法添加到实际的类中,如果是,编译器会选择该方法。
最佳答案
您必须查看所有可能定义了扩展方法的程序集。
查找用 ExtensionAttribute
修饰的类,然后是该类中也用 ExtensionAttribute
装饰的方法。然后检查第一个参数的类型,看看它是否与您感兴趣的类型匹配。
这是一些完整的代码。它可能会更严格(它不检查类型是否未嵌套,或者是否至少有一个参数)但它应该能助您一臂之力。
using System;
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Linq;
using System.Collections.Generic;
public static class FirstExtensions
{
public static void Foo(this string x) {}
public static void Bar(string x) {} // Not an ext. method
public static void Baz(this int x) {} // Not on string
}
public static class SecondExtensions
{
public static void Quux(this string x) {}
}
public class Test
{
static void Main()
{
Assembly thisAssembly = typeof(Test).Assembly;
foreach (MethodInfo method in GetExtensionMethods(thisAssembly,
typeof(string)))
{
Console.WriteLine(method);
}
}
static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly,
Type extendedType)
{
var query = from type in assembly.GetTypes()
where type.IsSealed && !type.IsGenericType && !type.IsNested
from method in type.GetMethods(BindingFlags.Static
| BindingFlags.Public | BindingFlags.NonPublic)
where method.IsDefined(typeof(ExtensionAttribute), false)
where method.GetParameters()[0].ParameterType == extendedType
select method;
return query;
}
}
关于c# - 识别扩展方法的反射(reflection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/299515/