反射识别扩展方法 [英] Reflection to Identify Extension Methods

查看:27
本文介绍了反射识别扩展方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C# 中是否有一种使用反射来确定方法是否已作为扩展方法添加到类中的技术?

In C# is there a technique using reflection to determine if a method has been added to a class as an extension method?

给定如下所示的扩展方法,是否可以确定已将 Reverse() 添加到字符串类中?

Given an extension method such as the one shown below is it possible to determine that Reverse() has been added to the string class?

public static class StringExtensions
{
    public static string Reverse(this string value)
    {
        char[] cArray = value.ToCharArray();
        Array.Reverse(cArray);
        return new string(cArray);
    }
}

我们正在寻找一种机制来在单元测试中确定开发人员适当地添加了扩展方法.尝试这样做的一个原因是,开发人员可能会将类似的方法添加到实际类中,如果是这样,编译器会选择该方法.

We're looking for a mechanism to determine in unit testing that the extension method was appropriately added by the developer. One reason to attempt this is that it is possible that a similar method would be added to the actual class by the developer and, if it was, the compiler will pick that method up.

推荐答案

您必须查看所有可能定义扩展方法的程序集.

You have to look in all the assemblies where the extension method may be defined.

查找用 ExtensionAttribute<修饰的类/code>,然后是该类中的方法,这些方法ExtensionAttribute 修饰.然后检查第一个参数的类型,看它是否与您感兴趣的类型匹配.

Look for classes decorated with ExtensionAttribute, and then methods within that class which are also decorated with ExtensionAttribute. Then check the type of the first parameter to see if it matches the type you're interested in.

这是一些完整的代码.它可能更严格(它不检查类型是否嵌套,或者至少有一个参数)但它应该可以帮助您.

Here's some complete code. It could be more rigorous (it's not checking that the type isn't nested, or that there is at least one parameter) but it should give you a helping hand.

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;
    }
}

这篇关于反射识别扩展方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆