logo
post image
user image

DIGITAL GENERATION

Muallif

June 9, 2024

168

C#'da Reflections'dan foydalanish

C#

Tip nusxasini dinamik yaratishda, tipnig mavjud ob'yekt bilan aloqasini ta'minlashda, mavjud ob'yektning tipini aniqlashda va uning metodlarini ishlatishda(chaqirishda) yoki uning maydonlari va xususiyatlariga ruxsat olishda Reflectiondan foydalaniladi.

Masalan,

string myStringValue="Learning reflections in C#";
System.Type type= myStringValue.GetType();
System.Console.WriteLine(type);

Natija:

Sytem.String

Ushbu misolda GetType orqali reflection ishlatildi va ob'yektning tipi aniqlandi.

Reflection – shunday jarayonki, unda dastur vaziyatga qarab o'z struktura va ko'rinishini o'zgartirishi mumkin.

1-Savol: Dastur ishlayotgan vaqtda biror string tipidagi o'zgaruvchining faqat nominigina bilgan holda uning qiymatini qanday o'zgartirish mumkin?

Javob:

class Program
    {
        private static string a="test1", b="test2", c="test3";
        private static string s = "test string";
        static void Main(string[] args)
        {
            Console.WriteLine("O'zgaruvchi nomini kiriting:");
            string varName = Console.ReadLine();
            Console.WriteLine("O'zgaruvchi yangi qiymatini kiriting:");
            string newValue = Console.ReadLine();
            Type t = typeof(Program);
            FieldInfo fieldInfo=t.GetField(varName,BindingFlags.NonPublic|BindingFlags.Static);
            if (fieldInfo != null)
            {
                string varInfo1 = string.Format("{0} o'zgaruvchining joriy qimati:{1}",fieldInfo.Name,fieldInfo.GetValue(null));
                Console.WriteLine(varInfo1);
                fieldInfo.SetValue(null,newValue);
                string varInfo2 = string.Format("{0} o'zgaruvchining yangi qimati:{1}", fieldInfo.Name, fieldInfo.GetValue(null));
                Console.WriteLine(varInfo2);
            }
            else Console.WriteLine("Bunday o'zgaruvchi aniqlanmagan!");
            Console.ReadLine();
        }
    }

Joriy koddagi assembly(project, ya'ni assemblyni build qilganda .exe yoki .dll fayl ko'rinishga o'tadi) tiplarni(projectdagi classlar, interfacelar,…) aniqlash.

Projectda quyidagilar aniqlangan bo'lsin:

namespace xyz.Test1.fullinfo
{
    public class ClassTest
    {
       //…
    }
}
namespace ReflactionTest
{
    abstract class AbstractClassTest
    {
       //…
    }
}
namespace ReflactionTest
{
    interface Interface1
    {
       //…
    }
}

Barcha assembly tiplar ro'yxatini quyidagi kod yordamida aniqlash mumkin:

namespace ReflactionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Type[] assemblyTypes = assembly.GetTypes();
            foreach (Type t in assemblyTypes)
                Console.WriteLine(t.Name);
            Console.ReadLine();
        }
    }
}

Natija:

ClassTest
ArstractClassTest
Interface1

Sinf nomi orqali undagi metodni Reflection yordamida ishlatish:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace ReflectionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Type testType = typeof(TestClass);
            ConstructorInfo ctor = testType.GetConstructor(System.Type.EmptyTypes);
            if(ctor != null)
            {
                object instance = ctor.Invoke(null);
                MethodInfo methodInfo = testType.GetMethod("TestMethod");
                Console.WriteLine(methodInfo.Invoke(instance, new object[] { 20 }));
            }
            Console.ReadKey();
        }
    }
    public class TestClass
    {
        private int testValue = 35;
        public int TestMethod(int numberToAdd)
        {
            return this.testValue + numberToAdd;
        }
    }
}

2-Savol: Base Calss "bolalari"ni qanday aniqlash mumkin?

1-Javob:

Masalan, BaseClass nomi BasePerson bo'lsa:

var result = AppDomain.CurrentDomain.GetAssemblies()
                       .SelectMany(assembly => assembly.GetTypes())
                       .Where(type => type.IsSubclassOf(typeof(BasePerson)));
            foreach (Type item in result)
            {
                var personObject = Activator.CreateInstance(item);
                MethodInfo methodInfo = item.GetMethod("<Person sinfidagi metod nomi>");
                //ParameterInfo[] parameters = methodInfo.GetParameters();
                object[] parameters = new object[] { parametr1,parametr2,…,parametrN };
                var methodResult = methodInfo.Invoke(personObject, parameters);
                     …
            }

2-JavobBaseLogic sinfi abstract shaklda aniqlangan va u check(column1,column2) metodiga ega, undan inherits olgan barcha sinflardning check metodi natijalarini olish:

var logicList = new List<BaseLogic>();
                var types = Assembly.GetExecutingAssembly().GetTypes();
                foreach (var type in types)
                {
                    if (type.IsSubclassOf(typeof(BaseLogic)))
                    {
                        logicList.Add((BaseLogic)Activator.CreateInstance(type));
                    }
                }

Ishlatishda:

logicList.Where(w=>w.Weight<=weight).ToList().ForEach(logic=>
            {
                primeryKeyColumn.Parent = _tables.Find(f => f.ID == primeryKeyColumn.ParentID);
                forignKeyColumn.Parent = _tables.Find(f => f.ID == forignKeyColumn.ParentID);
                var relationship = logic.Check(primeryKeyColumn,forignKeyColumn);
}

Kabi bo'ladi.

Izohlar