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

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

问题描述

在C#是有使用反射,以确定是否一个方法已被添加到一类作为扩展方法的技术

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

给定的延伸的方法,例如如下所示的是它能够确定反向()已经被添加到字符串类

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.

查找饰<一类href=\"http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.extensionattribute.aspx\"><$c$c>ExtensionAttribute,然后将该类是的装饰, 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.

下面是一些完整的code。这可能是更严格的(它不检查该类型不是嵌套的,或者说,至少有一个参数),但它应该给你伸出援助之手。

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天全站免登陆