Паролингизни унутдингизми?
Login
Left, Right, Center Left, Center, Right Center, Left, Right



Рефлексия (Reflection)

Рефлексия (Reflection)

c-sharpРефлексия (Reflection) - .NET нинг ажойиб хусусият бири хисобланади. Рефлексия assembly ва хар хил объектларни дастурни ишлаш вақтида ўрганиш имконини беради масалан, рефлексия орқали хохлаган объектни класслари, метод ва хоссалари хақида маълумот олиш ва унинг методларини чақириш мумкин.

Рефлексиядан фойдалана олишлик учун System.Reflection номлар макони ишлатилади.

Қуйидаги мисолда рефлексиядан фойдаланиб дастур ишлатаятган assembly лар рўйхатини олиш усули келтирилган

01.using System;
02.using System.Reflection;
03.
04.namespace CSharpdaRefleksiya
05.{
06.class ReferencedAssemblies
07.{
08.[STAThread]
09.static void Main(string[] args)
10.{
11.Assembly[] appAssemblies =
12.System.AppDomain.CurrentDomain.GetAssemblies ();
13.foreach (Assembly assembly in appAssemblies )
14.{
15.Console.WriteLine (assembly.FullName);
16.}
17.Console.ReadLine ();
18.}
19.}
20.}


Юқоридаги мисол ишлатиб юборилганида унинг натижаси қуйидагича бўлади:
mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
CSharpdaRefleksiya, Version=1.0.1882.29904, Culture=neutral, Publiс
...

System.AppDomain класси дастур ишловчи махсус ажратилган (изоляция қилинган) мухит яъни дастурни домени хисобланади. Шуни айтиб ўтиш лозимки, "изоляция" қилинишда дастур билан боғлиқ бўлган ресурслар - хотира, "поток"лар, "процесс"лар ва бошқалар киради. Хар бир дастурга ўз домени тузилади ва дастурга керакли бўлган барча assembly'лар ўз доменларига юкланади. Доменлараро мулоқот учун ўзига хос "механизм"лар мавжуд.
GetAssemblies() методи CSharpdaRefleksiya доменида юкланган assembly'лар рўйхатини қайтаради.

Аввало, Assembly.Load() дан фойдаланиб, assembly ни динамик тарзда юклаймиз:
1.public static Assembly.Load(AssemblyName)


MsCorLib.dll ни бериб юборамиз:
1.Assembly LoadedAssembly = Assembly.Load("mscorlib.dll");


assembly юкланиб бўлганида GetTypes() ни чақириб, турлар массивини олишимиз мумкин:
1.System.Type[] ExistingTypes = LoadedAssembly.GetTypes ();


Натижада бизга қайтарилган турлар класс, интерфейс ёки enumerator лар бўлиши мумкин.
01.using System;
02.using System.Reflection ;
03.namespace ReflectionDemoCSharp
04.{
05.class ReflectedTypes
06.{
07.[STAThread]
08.static void Main(string[] args)
09.{
10.Assembly LoadedAssembly = Assembly.Load ("mscorlib.dll");
11.System.Type[] ExistingTypes = LoadedAssembly.GetTypes ();
12.foreach(Type type in ExistingTypes)
13.Console.WriteLine (type.ToString ());
14.Console.WriteLine (ExistingTypes.Length +
15." Types Discovered in mscorlib.dll");
16.Console.ReadLine ();
17.}
18.}
19.}

Юқоридаги кодни натижасидан бир қисми:
System.Object
System.ICloneable
System.Collections.IEnumerable
System.Collections.ICollection
System.Collections.IList
System.Array
System.Array+SorterObjectArray
System.Array+SorterGenericArray
System.Collections.IEnumerator
1480 Types Discovered in mscorlib.dll


Келинг энди маълум аниқ турни барча такшил этувчиларини рўйхатини оламиз. Type.GetType(TypeName) методи System.Type объектини қайтаради. Биз Type.GetMembers() методи ёрдамида турнинг ташкил этувчиларини рўйхатини оламиз:
01.using System;
02.using System.Reflection ;
03.namespace ReflectionDemoCSharp
04.{
05.class ReflectedTypes
06.{
07.[STAThread]
08.static void Main(string[] args)
09.{
10.Type TypeToReflect = Type.GetType("System.Int32");
11.System.Reflection.MemberInfo[] Members =type.GetMembers();
12.Console.WriteLine ("Members of "+TypeToReflect.ToString ());
13.Console.WriteLine();
14.foreach (MemberInfo member in Members )
15.Console.WriteLine(member);
16.Console.ReadLine ();
17.}
18.}
19.}


Натижа:
Members of System.Int32
Int32 MaxValue
Int32 MinValue
System.String ToString(System.IFormatProvider)
System.TypeCode GetTypeCode()
System.String ToString(System.String, System.IFormatProvider)
Int32 CompareTo(System.Object)
Int32 GetHashCode()
Boolean Equals(System.Object)
System.String ToString()
System.String ToString(System.String)
Int32 Parse(System.String)
Int32 Parse(System.String, System.Globalization.NumberStyles)
Int32 Parse(System.String, System.IFormatProvider)
Int32 Parse(System.String, System.Globalization.NumberStyles, System.IFormatProvider)
System.Type GetType()

Қуйида рефлексиядан фойдаланишда бир қанча фойдали методлар рўйхати келтирилди:

  • System.Reflection.MemberInfo[] Members =type.GetMembers() — турни барча ташкил этувчиларини қайтаради.
  • System.Reflection.MethodInfo[] Methods =Type.GetMethods() — турни фақат методларини қайтаради.
  • System.Reflection.FieldInfo[] Fields =Type.GetFields() — турни майдонларини қайтаради.
  • System.Reflection.PropertyInfo[] Properties = type.GetProperties () — турни хоссаларини қайтаради.
  • System.Reflection.EventInfo[] Events = type.GetEvents() — турни ходисаларини қайтаради.
  • System.Reflection.ConstructorInfo[] Constructors = type.GetConstructors () — турни конструкторларини қайтаради.
  • System.Type[] Interfaces = type.GetInterfaces() — турни интерфейсларини қайтаради.


type.InvokeMember()
ёрдамида методларни номини кўрсатиб чақириш мумкин.
InvokeMember() нинг аргументлари қуйидагилар:

  1. Чақирилаятган методни номи. Қатор кўринишида берилади.
  2. BindingFlags аъзолари. BindingFlags ёрдамида турларни изланиши бошқарилади. Масалан, static методлар дан қидириш ва хоказо.
  3. Binder объекти, боғланиш жараёнини ва хоссаларини аниқлайди. null хам бўлиши мумкин.
  4. Метод чақирилиши керак бўлган объект.
  5. Методга бериб юбориладиган аргументлар массиви.
01.using System;
02.using System.Reflection ;
03.namespace ReflectionDemoCSharp
04.{
05.class ReflectedTypes
06.{
07.[STAThread]
08.static void Main(string[] args)
09.{
10.Type TypeToReflect = Type.GetType("System.String");
11.object result = null;
12.object[] arguments = {"abc","xyz"};
13.result = TypeToReflect.InvokeMember ("Equals",
14.BindingFlags.InvokeMethod, null, result, arguments);
15.Console.WriteLine (result.ToString ());
16.Console.ReadLine ();
17.}
18.}
19.}

Натижа false бўлади.

Қуйида рефлексияга бир қанча мисоллар келтирилган. Уларда Test.dll assembly'си юкланади, Calculator классига мансуб бўлган объект тузилади хамда унинг аъзолари билан ишлаймиз:
01.// Test.dll библиотекасдан assembly'ни динамик тарзда юклаймиз:
02.Assembly testAssembly = Assembly.LoadFile(@"c:\Test.dll");
03.
04.// хозиргина юкланган assembly дан Calculator классини турини аниқлаб оламиз:
05.Type calcType = testAssembly.GetType("Test.Calculator");
06.
07.// Calculator классига мансуб бўлган объектни тузамиз:
08.object calcInstance = Activator.CreateInstance(calcType);
09.
10.// Number хоссаси хақида маълумот оламиз:
11.PropertyInfo numberPropertyInfo = calcType.GetProperty("Number");
12.
13.// Number хоссассини қийматини оламиз.
14.double value = (double)numberPropertyInfo.GetValue(calcInstance, null);
15.
16.// Number хоссасига қиймат белгилаймиз:
17.numberPropertyInfo.SetValue(calcInstance, 10.0, null);
18.
19.// Статик Pi хоссаси хақида маълумот оламиз:
20.PropertyInfo piPropertyInfo = calcType.GetProperty("Pi");
21.
22.// Статик Pi хоссасини қийматини оламиз:
23.double piValue = (double)piPropertyInfo.GetValue(null, null);
24.
25.// public кўриниш доирасидаги Clear() методини чақирамиз:
26.calcType.InvokeMember("Clear",
27.BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, calcInstance, null);
28.
29.// private кўриниш доирасидаги DoClear() методини чақирамиз:
30.calcType.InvokeMember("DoClear",
31.BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, null, calcInstance, null);
32.
33.
34.// Add(double number) методини чақирамиз:
35.double value = (double)calcType.InvokeMember("Add",
36.BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, calcInstance, new object[] { 20.0 });
37.
38.// GetPi() статик методини чақирамиз:
39.double piValue = (double)calcType.InvokeMember("GetPi",
40.BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, null);
41.
42.// private кўриниш доирасидаги _number ўзгарувчисини қийматини оламиз:
43.double value = (double)calcType.InvokeMember("_number",
44.BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic, null, calcInstance, null);


Фарход Дадажонов

Manba: http://virtualdars.uz

Share