Отражение для идентификации дополнительных методов

73
задан M.Babcock 31 December 2012 в 19:31
поделиться

3 ответа

Необходимо посмотреть во всех блоках, где дополнительный метод может быть определен.

Ищут классы, украшенные 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;
    }
}
107
ответ дан Jon Skeet 24 November 2019 в 12:20
поделиться

Одна причина попытаться это - то, что возможно, что похожий метод был бы добавлен к фактическому классу разработчиком и, если бы это было, компилятор заберет тот метод.

  • предположим дополнительный метод пустой Foo (этот Клиент someCustomer) определяется.
  • предположим, также, что Клиент изменяется и метод , пустой Foo () добавляется.
  • Затем новый метод на Клиенте покроет/скроет дополнительный метод.

единственный способ назвать старый метод Foo в той точке:

CustomerExtension.Foo(myCustomer);
2
ответ дан Amy B 24 November 2019 в 12:20
поделиться

Для прояснения мысли, Jon замял... "Добавление" дополнительного метода к классу не изменяет класс всегда. Это - просто определенное вращение выполненного компилятором C#.

Так, с помощью примера, можно записать

string rev = myStr.Reverse();

, но MSIL, записанный в блок, будет точно, как будто Вы записали его:

string rev = StringExtensions.Reverse(myStr);

компилятор просто позволяет Вам дурачить себя, заставляя думать, Вы называете метод Строки.

3
ответ дан James Curran 24 November 2019 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: