c# - 识别扩展方法的反射(reflection)

标签 c# reflection extension-methods

在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/

相关文章:

c# - 通用扩展方法测试

c# - Entity Framework - CommitFailureHandler.ClearTransactionHistory()

c# - 并行嵌套操作返回奇怪的结果

reflection - R7RS Scheme的反射能力

c# - MissingMethodException 但我不明白为什么

c# - EF 扩展 AddIfNotExists 本地 lambda

c# - C# NUnit 的 BDD

c# - 温莎城堡 Nhibernate 设施延迟加载

php - 在运行时修改方法/函数

c# - 如何在 VB 代码中调用 C# 扩展方法