Рефлексия в C#

До недавнего времени я не использовал рефлексию в C#, да и не особо представлял, для чего она нужна. Но, как оказалось, в некоторых случаях это довольно ценный, а порой и незаменимый инструмент.
Что же такое рефлексия? Если говорить кратко, то это система, предоставляющая выполняющему коду информацию о нём же самом. То есть позволяет читать выполняющему коду информацию о метаданных, которые он генерирует.
Рефлексия в C# активно использует класс Type. Подробно о нём можно узнать здесь.
 Так для чего же может понадобиться рефлексия. Для различных исследований типа. Например можно получить список полей в классе, при этом можно получить как открытые поля, так и закрытые. Например, в следующем примере можно получить список всех полей класса и названия их типов.

using System;
using System.Reflection;

namespace TestReflection
{
    class Program
    {
        static void Main(string[] args)
        {
            var testClass = new TestReflectionClass();
            Type type = testClass.GetType();
            var fields = type.GetFields(BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public);
            foreach (var fieldInfo in fields)
            {
                Console.WriteLine("{0}: {1}", fieldInfo.Name, fieldInfo.FieldType);
            }
        }
    }

    public class TestReflectionClass
    {
        private string _firstName;
        private string _lastName;
        private int _old;
        public string Description;

    }
}


Выведет на экран:

Еще один пример, показывающий, как можно использовать методы класса через рефлексию:

using System;
using System.Reflection;

namespace TestReflection
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t = typeof(String);

            MethodInfo substr = t.GetMethod("Substring",
                new Type[] { typeof(int), typeof(int) });

            Object result =
                substr.Invoke("Hello, World!", new Object[] { 7, 5 });
            Console.WriteLine("{0} returned \"{1}\".", substr, result);
        }
    }

}


Еще один интересный пример. Но для начала вопрос:  можно ли вызвать private метод из другого класса?
Ответ, естественно да, хотя нижеприведённый пример нарушает принципы ООП, но такая возможность присутствует.

using System;
using  System.Reflection;

namespace TestReflection
{
    class Program
    {
        static void Main(string[] args)
        {
            var testClass = new TestReflectionClass();
            Type type = testClass.GetType();
            MethodInfo info = type.GetMethod("PrivateMethod", BindingFlags.Instance | BindingFlags.NonPublic);
            info.Invoke(testClass, null);
        }
    }

    public class TestReflectionClass
    {
        private void PrivateMethod()
        {
            Console.WriteLine("This is private method");
        }
    }
}

Ссылки по теме:
http://msdn.microsoft.com/ru-ru/library/system.type%28v=vs.110%29.aspx
http://msdn.microsoft.com/ru-ru/library/system.reflection.bindingflags%28v=vs.110%29.aspx

Комментарии (2) -

Катерина 18.04.2017 15:54:24

Всё равно не понятно в каких случаях это может пригодиться в жизни

Андрей 18.04.2017 16:28:30

Первое что приходит в голову, это, например, обработка кастомных аттрибутов.

Добавить комментарий