Aracılığıyla paylaş


Yansıtma (C++/ CLI)

Yansıma, bilinen veri türlerinin bir çalışma zamanında denetlenmesine olanak tanır.Yansıma, verilen derlemedeki veri türlerinin ve verilen sınıftaki üyelerin numaralanmasına veya değer türünün bulunmasına olanak tanır.Bu, türün bilinip bilinmediğine ya da derleme zamanında bahsedilip bahsedilmediğine bakmaksızın geçerlidir.Bu, yansımayı geliştirme ve kod yönetme araçları için yararlı bir özellik haline getirir.

Belirtilen derleme adının, derleme sürümünü, kültürünü ve imzalama bilgilerini içeren tanımlayıcı ad (bkz. Tanımlayıcı Ada Sahip Derlemeler) olduğunu unutmayın.Ayrıca, veri türünün tanımlandığı ad alanı adının, temel sınıf adı ile birlikte alınabilir olduğunu da unutmayın.

Yansıma özelliklerine erişmenin en yaygın yolu GetType yöntemi aracılığıyladır.Bu yöntem, tüm atık olarak toplanmış sınıfların türediği System::Object öğesi tarafından verilmektedir.

Visual C++ derleyicisine sahip bir.exe yapısında yansımaya izin verilir ancak .exe dosyasının /clr:pure veya /clr:safe derleyici seçenekleriyle yapılandırılmış olması gerekir.Daha fazla bilgi için bkz. /CLR (ortak dil çalışma zamanı derleme).

Bu bölümdeki konular:

Daha fazla bilgi için bkz. System.Reflection Ad Alanı

Örnek

GetType yöntemi nesne dayandırıldığında türü tanımlayan bir Type sınıf nesnesine bir işaretçi döndürür.(Tür nesnesi özel bilgiler içermez.) Böyle bir öğe türün aşağıdaki şekilde görüntülenebilecek tam adıdır:

Tür adı, .NET sözdiziminde gösterilen ad alanı dahil olmak üzere türün tanımlandığı tüm kapsamı, kapsam çözüm operatörü gibi bir noktayla birlikte içerir.

// vcpp_reflection.cpp
// compile with: /clr
using namespace System;
int main() {
   String ^ s = "sample string";
   Console::WriteLine("full type name of '{0}' is '{1}'", s, s->GetType());
}
  

Değer türleri GetType işlemi ile de kullanılabilir. Ancak önce kutulanmaları gerekir.

// vcpp_reflection_2.cpp
// compile with: /clr
using namespace System;
int main() {
   Int32 i = 100; 
   Object ^ o = i;
   Console::WriteLine("type of i = '{0}'", o->GetType());
}
  

GetType yönteminde olduğu gibi, typeid (C++ Bileşen Uzantıları) işleci Tip nesnesine bir işaretçi döndürür, yani bu kod System.Int32 tip ismini gösterir.Tür adlarını en temel özellik veya yansıma üzerinde görüntüleyin ancak daha kullanışlı olması muhtemel olan teknik numaralandırılmış türler için geçerli değerleri incelemek veya keşfetmektir.Bu, her biri metin biçiminde sabit listesi değeri içeren, dize dizisini döndüren, statik Enum::GetNames işlevini kullanarak başarılabilir.Aşağıdaki örnek Seçenekler (CLR) numaralandırması için değer numaralandırma değerlerini tanımlayan bir dizeler dizisi alır ve bunları bir döngüde görüntüler.

Seçenekler numaralandırmasına dördüncü bir seçenek eklendiyse, numaralandırma ayrı bir derlemede tanımlansa bile, bu kod yeni seçeneği yeniden derleme gerekmeksizin rapor eder.

// vcpp_reflection_3.cpp
// compile with: /clr
using namespace System;

enum class Options {   // not a native enum
   Option1, Option2, Option3
};

int main() {
   array<String^>^ names = Enum::GetNames(Options::typeid);

   Console::WriteLine("there are {0} options in enum '{1}'", 
               names->Length, Options::typeid);

   for (int i = 0 ; i < names->Length ; i++)
      Console::WriteLine("{0}: {1}", i, names[i]);

   Options o = Options::Option2;
   Console::WriteLine("value of 'o' is {0}", o);
}
  

GetType nesnesi bir türü incelemek için kullanılabilecek birçok üye ve özellikleri destekler.Bu kod şu bilgilerden bazılarını alır ve görüntüler:

// vcpp_reflection_4.cpp
// compile with: /clr
using namespace System;
int main() {
   Console::WriteLine("type information for 'String':");
   Type ^ t = String::typeid;

   String ^ assemblyName = t->Assembly->FullName;
   Console::WriteLine("assembly name: {0}", assemblyName);

   String ^ nameSpace = t->Namespace;
   Console::WriteLine("namespace: {0}", nameSpace);

   String ^ baseType = t->BaseType->FullName;
   Console::WriteLine("base type: {0}", baseType);

   bool isArray = t->IsArray;
   Console::WriteLine("is array: {0}", isArray);

   bool isClass = t->IsClass;
   Console::WriteLine("is class: {0}", isClass);
}
  

Yansıma ayrıca bir derlemedeki türlerin ve sınıflardaki üyelerin numaralandırılmasına olanak tanır.Bu özelliği göstermek için basit bir sınıf tanımlayın:

// vcpp_reflection_5.cpp
// compile with: /clr /LD
using namespace System;
public ref class TestClass {
   int m_i;
public:
   TestClass() {}
   void SimpleTestMember1() {}
   String ^ SimpleMember2(String ^ s) { return s; } 
   int TestMember(int i) { return i; }
   property int Member {
      int get() { return m_i; }
      void set(int i) { m_i = i; }
   }
};

Yukarıdaki kod vcpp_reflection_6.dll denilen bir dll içine derlenmişse, bu derlemenin içeriğini incelemek için yansıma kullanabilirsiniz.Bu, Assembly::Load statik yansıma API'si işlevinin derlemeyi yüklemesini içerir.Bu işlev, bir Derleme nesnesinin adresini döndürür; ardından bu nesne içindeki modüller ve türler hakkında sorgulanabilir.

Yansıma sistemi, derlemeyi başarılı bir şekilde yükledikten sonra Tür nesneleri dizisi Assembly::GetTypes işlevi ile alınır.Her dizi öğesi farklı bir tür hakkında bilgi içerir ancak bu çalışmada yalnızca bir sınıf tanımlanmıştır.Bir döngü kullanarak bu dizideki her bir Tür, Type::GetMembers işlevini kullanan tür üyeleri hakkında sorgulanır.Bu işlev bir MethodInfo nesneleri dizisi döndürür; her nesne üye işlevi, veri üyesi veya türdeki özellik hakkında bilgi içerir.

Yöntem listesinde TestClass içinde açıkça tanımlanmış işlevler ve System::Object sınıfından dolaylı olarak devralınmış işlevler bulunur.Visual C++ sözdiziminde değil .NET'te açıklanmalarının parçası olarak, get/set işlevlerinin eriştiği temel veri üyeleri olarak görünür.Alma/ayarlama işlevleri listede sıradan yöntemler olarak görünür.Yansıma ortak dil çalışma zamanında desteklenir, Visual C++ derleyici tarafından desteklenmez.

Her ne kadar, bu kodu tanımladığınız derlemeyi incelemek için kullanmış olsanız da, onu .NET derlemelerini incelemek için de kullanabilirsiniz.TestAssembly derlemesini mscorlib olarak değiştirirseniz, her türe yönelik bir listeleme ve mscrlib.dll dosyası üzerinde tanımlanmış olan yöntem görüntülenir.

// vcpp_reflection_6.cpp
// compile with: /clr
using namespace System;
using namespace System::IO;
using namespace System::Reflection;
int main() {
   Assembly ^ a = nullptr;
   try {
      // load assembly -- do not use file extension
      // will look for .dll extension first
      // then .exe with the filename
      a = Assembly::Load("vcpp_reflection_5");
   }
   catch (FileNotFoundException ^ e) {
      Console::WriteLine(e->Message);
      return -1;
   }

   Console::WriteLine("assembly info:");
   Console::WriteLine(a->FullName);
   array<Type^>^ typeArray = a->GetTypes();

   Console::WriteLine("type info ({0} types):", typeArray->Length);

   int totalTypes = 0;
   int totalMembers = 0;
   for (int i = 0 ; i < typeArray->Length ; i++) {
      // retrieve array of member descriptions
      array<MemberInfo^>^ member = typeArray[i]->GetMembers();

      Console::WriteLine("  members of {0} ({1} members):", 
      typeArray[i]->FullName, member->Length);
      for (int j = 0 ; j < member->Length ; j++) {
         Console::Write("       ({0})", 
         member[j]->MemberType.ToString() );
         Console::Write("{0}  ", member[j]);
         Console::WriteLine("");
         totalMembers++;
      }
      totalTypes++;
   }
   Console::WriteLine("{0} total types, {1} total members",
   totalTypes, totalMembers);
}

Ayrıca bkz.

Diğer Kaynaklar

.net programlama Visual C++