c# – 识别扩展方法的反射

在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# – 识别扩展方法的反射 - 代码日志