Как я вызываю дополнительный метод с помощью отражения?

Соглашение в моей команде состоит в том, чтобы использовать debug, если что-то вычисляется в сообщении, тогда как info используется для простого текста. Таким образом, в действительности info покажет Вам, что происходит, и debug покажет значения вещей, которые происходят.

31
задан Jon Simpson 20 September 2009 в 23:15
поделиться

4 ответа

Как говорили другие, методы расширений - это магия компилятора, вы всегда можете использовать VS правой кнопкой мыши, перейти к определению, чтобы найти реальный тип, реализующий статический метод.

Оттуда он получает довольно волосатая . Где перегружен, поэтому вам нужно найти фактическое определение, которое соответствует желаемой подписи. GetMethod имеет некоторые ограничения на общие типы, поэтому вам нужно найти реальный с помощью поиска.

Как только вы найдете метод, вы должны сделать MethodInfo специфичным с помощью вызова MakeGenericMethod .

Вот полный рабочий пример:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication9 {
    class Program {

        class MyObject {
            public string Name { get; set; }
        } 

        public static void CallWhereMethod() {
            List<MyObject> myObjects = new List<MyObject>() { 
                new MyObject { Name = "Jon Simpson" },
                new MyObject { Name = "Jeff Atwood" }
            };


            Func<MyObject, bool> NameEquals = BuildEqFuncFor<MyObject>("Name", "Jon Simpson");


            // The Where method lives on the Enumerable type in System.Linq
            var whereMethods = typeof(System.Linq.Enumerable)
                .GetMethods(BindingFlags.Static | BindingFlags.Public)
                .Where(mi => mi.Name == "Where"); 

            Console.WriteLine(whereMethods.Count());
            // 2 (There are 2 methods that are called Where)

            MethodInfo whereMethod = null;
            foreach (var methodInfo in whereMethods) {
                var paramType = methodInfo.GetParameters()[1].ParameterType;
                if (paramType.GetGenericArguments().Count() == 2) {
                    // we are looking for  Func<TSource, bool>, the other has 3
                    whereMethod = methodInfo;
                }
            }

            // we need to specialize it 
            whereMethod = whereMethod.MakeGenericMethod(typeof(MyObject));

            var ret = whereMethod.Invoke(myObjects, new object[] { myObjects, NameEquals }) as IEnumerable<MyObject>;

            foreach (var item in ret) {
                Console.WriteLine(item.Name);
            }
            // outputs "Jon Simpson"

        }

        public static Func<T, bool> BuildEqFuncFor<T>(string prop, object val) {
            return t => t.GetType().InvokeMember(prop, BindingFlags.GetProperty,
                                                 null, t, null) == val;
        }

        static void Main(string[] args) {
            CallWhereMethod();
            Console.ReadKey();

        }
    }
}
48
ответ дан 27 November 2019 в 22:08
поделиться

Методы расширения - это просто статические методы под водой. Вызов метода расширения, например foo.Frob ( arguments ), на самом деле просто SomeClass.Frob (foo, arguments ). В случае метода Where вы ищете System.Linq.Enumerable.Where. Итак, получите тип Enumerable и вызовите для него Where.

10
ответ дан 27 November 2019 в 22:08
поделиться

Ваш пример кода немного сбивает с толку ... если MyObject не является перечислимым.

Используя отражение, вам нужно будет вызвать Where в System.Linq.Enumerable, передав перечислимое значение, которое вы хотите преформировать Where on.

1
ответ дан 27 November 2019 в 22:08
поделиться

Методы расширения - это трюк компилятора c #, и они не существуют в рассматриваемом типе. Они (именно эти) существуют в статических классах в пространствах имен System.Linq. Я предлагаю отразить это в рефлекторе, а затем вызвать рефлексию над этими типами.

0
ответ дан 27 November 2019 в 22:08
поделиться
Другие вопросы по тегам:

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