Memuat dan menggunakan jenis secara dinamis
Refleksi menyediakan infrastruktur yang digunakan oleh pengkompilasi bahasa pemrogram untuk menerapkan pengikatan terlambat implisit. Pengikatan adalah proses menemukan deklarasi (yaitu, implementasi) yang sesuai dengan jenis yang ditentukan secara unik. Ketika proses ini terjadi pada waktu proses daripada pada waktu kompilasi, proses ini disebut pengikatan terlambat. Visual Basic memungkinkan Anda menggunakan pengikatan terlambat implisit dalam kode Anda; pengkompilasi Visual Basic memanggil metode pembantu yang menggunakan pantulan untuk mendapatkan jenis objek. Argumen yang diteruskan ke metode pembantu menyebabkan metode yang sesuai dipanggil pada durasi. Argumen ini adalah instans (objek) untuk memanggil metode, nama metode yang dipanggil (string), dan argumen yang diteruskan ke metode yang dipanggil (array objek).
Dalam contoh berikut, pengkompilasi Visual Basic menggunakan refleksi secara implisit untuk memanggil metode pada objek yang jenisnya tidak diketahui pada waktu kompilasi. Kelas HelloWorld
memiliki PrintHello
metode yang mencetak "Halo Dunia" yang digabungkan dengan beberapa teks yang diteruskan ke PrintHello
metode . Metode PrintHello
yang disebut dalam contoh ini sebenarnya adalah Type.InvokeMember; kode Visual Basic memungkinkan PrintHello
metode untuk dipanggil seolah-olah jenis objek (helloObj
) dikenal pada waktu kompilasi (pengikatan awal) daripada pada waktu proses (pengikatan terlambat).
Module Hello
Sub Main()
' Sets up the variable.
Dim helloObj As Object
' Creates the object.
helloObj = new HelloWorld()
' Invokes the print method as if it was early bound
' even though it is really late bound.
helloObj.PrintHello("Visual Basic Late Bound")
End Sub
End Module
Pengikatan kustom
Selain digunakan secara implisit oleh kompilator untuk pengikatan terlambat, refleksi dapat digunakan secara eksplisit dalam kode untuk mencapai pengikatan terlambat.
Runtime bahasa umum mendukung beberapa bahasa pemrograman, dan aturan pengikatan bahasa ini berbeda. Dalam kasus terikat awal, generator kode dapat sepenuhnya mengontrol pengikatan ini. Namun, dalam pengikatan akhir melalui refleksi, pengikatan harus dikontrol oleh pengikatan yang disesuaikan. Kelas Binder memberikan kontrol kustom atas pemilihan dan pemanggilan anggota.
Dengan menggunakan pengikatan kustom, Anda dapat memuat rakitan pada durasi, mendapatkan informasi tentang jenis dalam rakitan tersebut, menentukan jenis yang Anda inginkan, lalu memanggil metode atau bidang akses atau properti pada jenis tersebut. Teknik ini berguna jika Anda tidak tahu jenis objek pada waktu kompilasi, seperti ketika jenis objek bergantung pada input pengguna.
Contoh berikut menunjukkan pengikat kustom sederhana yang tidak menyediakan konversi jenis argumen. Kode untuk Simple_Type.dll
mendahului contoh utama. Pastikan untuk membangun Simple_Type.dll
lalu menyertakan referensi ke dalam proyek pada waktu build.
// Code for building SimpleType.dll.
using namespace System;
using namespace System::Reflection;
using namespace System::Globalization;
namespace Simple_Type
{
public ref class MySimpleClass
{
public:
void MyMethod(String^ str, int i)
{
Console::WriteLine("MyMethod parameters: {0}, {1}", str, i);
}
void MyMethod(String^ str, int i, int j)
{
Console::WriteLine("MyMethod parameters: {0}, {1}, {2}",
str, i, j);
}
};
}
using namespace Simple_Type;
namespace Custom_Binder
{
// ****************************************************
// A simple custom binder that provides no
// argument type conversion.
// ****************************************************
public ref class MyCustomBinder : Binder
{
public:
virtual MethodBase^ BindToMethod(
BindingFlags bindingAttr,
array<MethodBase^>^ match,
array<Object^>^% args,
array<ParameterModifier>^ modifiers,
CultureInfo^ culture,
array<String^>^ names,
Object^% state) override
{
if (match == nullptr)
{
throw gcnew ArgumentNullException("match");
}
// Arguments are not being reordered.
state = nullptr;
// Find a parameter match and return the first method with
// parameters that match the request.
for each (MethodBase^ mb in match)
{
array<ParameterInfo^>^ parameters = mb->GetParameters();
if (ParametersMatch(parameters, args))
{
return mb;
}
}
return nullptr;
}
virtual FieldInfo^ BindToField(BindingFlags bindingAttr,
array<FieldInfo^>^ match, Object^ value, CultureInfo^ culture) override
{
if (match == nullptr)
{
throw gcnew ArgumentNullException("match");
}
for each (FieldInfo^ fi in match)
{
if (fi->GetType() == value->GetType())
{
return fi;
}
}
return nullptr;
}
virtual MethodBase^ SelectMethod(
BindingFlags bindingAttr,
array<MethodBase^>^ match,
array<Type^>^ types,
array<ParameterModifier>^ modifiers) override
{
if (match == nullptr)
{
throw gcnew ArgumentNullException("match");
}
// Find a parameter match and return the first method with
// parameters that match the request.
for each (MethodBase^ mb in match)
{
array<ParameterInfo^>^ parameters = mb->GetParameters();
if (ParametersMatch(parameters, types))
{
return mb;
}
}
return nullptr;
}
virtual PropertyInfo^ SelectProperty(
BindingFlags bindingAttr,
array<PropertyInfo^>^ match,
Type^ returnType,
array<Type^>^ indexes,
array<ParameterModifier>^ modifiers) override
{
if (match == nullptr)
{
throw gcnew ArgumentNullException("match");
}
for each (PropertyInfo^ pi in match)
{
if (pi->GetType() == returnType &&
ParametersMatch(pi->GetIndexParameters(), indexes))
{
return pi;
}
}
return nullptr;
}
virtual Object^ ChangeType(
Object^ value,
Type^ myChangeType,
CultureInfo^ culture) override
{
try
{
Object^ newType;
newType = Convert::ChangeType(value, myChangeType);
return newType;
}
// Throw an InvalidCastException if the conversion cannot
// be done by the Convert.ChangeType method.
catch (InvalidCastException^)
{
return nullptr;
}
}
virtual void ReorderArgumentArray(array<Object^>^% args,
Object^ state) override
{
// No operation is needed here because BindToMethod does not
// reorder the args array. The most common implementation
// of this method is shown below.
// ((BinderState^)state).args.CopyTo(args, 0);
}
// Returns true only if the type of each object in a matches
// the type of each corresponding object in b.
private:
bool ParametersMatch(array<ParameterInfo^>^ a, array<Object^>^ b)
{
if (a->Length != b->Length)
{
return false;
}
for (int i = 0; i < a->Length; i++)
{
if (a[i]->ParameterType != b[i]->GetType())
{
return false;
}
}
return true;
}
// Returns true only if the type of each object in a matches
// the type of each corresponding entry in b.
bool ParametersMatch(array<ParameterInfo^>^ a, array<Type^>^ b)
{
if (a->Length != b->Length)
{
return false;
}
for (int i = 0; i < a->Length; i++)
{
if (a[i]->ParameterType != b[i])
{
return false;
}
}
return true;
}
};
public ref class MyMainClass
{
public:
static void Main()
{
// Get the type of MySimpleClass.
Type^ myType = MySimpleClass::typeid;
// Get an instance of MySimpleClass.
MySimpleClass^ myInstance = gcnew MySimpleClass();
MyCustomBinder^ myCustomBinder = gcnew MyCustomBinder();
// Get the method information for the particular overload
// being sought.
MethodInfo^ myMethod = myType->GetMethod("MyMethod",
BindingFlags::Public | BindingFlags::Instance,
myCustomBinder, gcnew array<Type^> {String::typeid,
int::typeid}, nullptr);
Console::WriteLine(myMethod->ToString());
// Invoke the overload.
myType->InvokeMember("MyMethod", BindingFlags::InvokeMethod,
myCustomBinder, myInstance,
gcnew array<Object^> {"Testing...", (int)32});
}
};
}
int main()
{
Custom_Binder::MyMainClass::Main();
}
// Code for building SimpleType.dll.
using System;
using System.Reflection;
using System.Globalization;
using Simple_Type;
namespace Simple_Type
{
public class MySimpleClass
{
public void MyMethod(string str, int i)
{
Console.WriteLine("MyMethod parameters: {0}, {1}", str, i);
}
public void MyMethod(string str, int i, int j)
{
Console.WriteLine("MyMethod parameters: {0}, {1}, {2}",
str, i, j);
}
}
}
namespace Custom_Binder
{
class MyMainClass
{
static void Main()
{
// Get the type of MySimpleClass.
Type myType = typeof(MySimpleClass);
// Get an instance of MySimpleClass.
MySimpleClass myInstance = new MySimpleClass();
MyCustomBinder myCustomBinder = new MyCustomBinder();
// Get the method information for the particular overload
// being sought.
MethodInfo myMethod = myType.GetMethod("MyMethod",
BindingFlags.Public | BindingFlags.Instance,
myCustomBinder, new Type[] {typeof(string),
typeof(int)}, null);
Console.WriteLine(myMethod.ToString());
// Invoke the overload.
myType.InvokeMember("MyMethod", BindingFlags.InvokeMethod,
myCustomBinder, myInstance,
new Object[] {"Testing...", (int)32});
}
}
// ****************************************************
// A simple custom binder that provides no
// argument type conversion.
// ****************************************************
class MyCustomBinder : Binder
{
public override MethodBase BindToMethod(
BindingFlags bindingAttr,
MethodBase[] match,
ref object[] args,
ParameterModifier[] modifiers,
CultureInfo culture,
string[] names,
out object state)
{
if (match == null)
{
throw new ArgumentNullException("match");
}
// Arguments are not being reordered.
state = null;
// Find a parameter match and return the first method with
// parameters that match the request.
foreach (MethodBase mb in match)
{
ParameterInfo[] parameters = mb.GetParameters();
if (ParametersMatch(parameters, args))
{
return mb;
}
}
return null;
}
public override FieldInfo BindToField(BindingFlags bindingAttr,
FieldInfo[] match, object value, CultureInfo culture)
{
if (match == null)
{
throw new ArgumentNullException("match");
}
foreach (FieldInfo fi in match)
{
if (fi.GetType() == value.GetType())
{
return fi;
}
}
return null;
}
public override MethodBase SelectMethod(
BindingFlags bindingAttr,
MethodBase[] match,
Type[] types,
ParameterModifier[] modifiers)
{
if (match == null)
{
throw new ArgumentNullException("match");
}
// Find a parameter match and return the first method with
// parameters that match the request.
foreach (MethodBase mb in match)
{
ParameterInfo[] parameters = mb.GetParameters();
if (ParametersMatch(parameters, types))
{
return mb;
}
}
return null;
}
public override PropertyInfo SelectProperty(
BindingFlags bindingAttr,
PropertyInfo[] match,
Type returnType,
Type[] indexes,
ParameterModifier[] modifiers)
{
if (match == null)
{
throw new ArgumentNullException("match");
}
foreach (PropertyInfo pi in match)
{
if (pi.GetType() == returnType &&
ParametersMatch(pi.GetIndexParameters(), indexes))
{
return pi;
}
}
return null;
}
public override object ChangeType(
object value,
Type myChangeType,
CultureInfo culture)
{
try
{
object newType;
newType = Convert.ChangeType(value, myChangeType);
return newType;
}
// Throw an InvalidCastException if the conversion cannot
// be done by the Convert.ChangeType method.
catch (InvalidCastException)
{
return null;
}
}
public override void ReorderArgumentArray(ref object[] args,
object state)
{
// No operation is needed here because BindToMethod does not
// reorder the args array. The most common implementation
// of this method is shown below.
// ((BinderState)state).args.CopyTo(args, 0);
}
// Returns true only if the type of each object in a matches
// the type of each corresponding object in b.
private bool ParametersMatch(ParameterInfo[] a, object[] b)
{
if (a.Length != b.Length)
{
return false;
}
for (int i = 0; i < a.Length; i++)
{
if (a[i].ParameterType != b[i].GetType())
{
return false;
}
}
return true;
}
// Returns true only if the type of each object in a matches
// the type of each corresponding entry in b.
private bool ParametersMatch(ParameterInfo[] a, Type[] b)
{
if (a.Length != b.Length)
{
return false;
}
for (int i = 0; i < a.Length; i++)
{
if (a[i].ParameterType != b[i])
{
return false;
}
}
return true;
}
}
}
' Code for building SimpleType.dll.
Imports System.Reflection
Imports System.Globalization
Imports Simple_Type
Namespace Simple_Type
Public Class MySimpleClass
Public Sub MyMethod(str As String, i As Integer)
Console.WriteLine("MyMethod parameters: {0}, {1}", str, i)
End Sub
Public Sub MyMethod(str As String, i As Integer, j As Integer)
Console.WriteLine("MyMethod parameters: {0}, {1}, {2}",
str, i, j)
End Sub
End Class
End Namespace
Namespace Custom_Binder
Class MyMainClass
Shared Sub Main()
' Get the type of MySimpleClass.
Dim myType As Type = GetType(MySimpleClass)
' Get an instance of MySimpleClass.
Dim myInstance As New MySimpleClass()
Dim myCustomBinder As New MyCustomBinder()
' Get the method information for the particular overload
' being sought.
Dim myMethod As MethodInfo = myType.GetMethod("MyMethod",
BindingFlags.Public Or BindingFlags.Instance,
myCustomBinder, New Type() {GetType(String),
GetType(Integer)}, Nothing)
Console.WriteLine(myMethod.ToString())
' Invoke the overload.
myType.InvokeMember("MyMethod", BindingFlags.InvokeMethod,
myCustomBinder, myInstance,
New Object() {"Testing...", CInt(32)})
End Sub
End Class
' ****************************************************
' A simple custom binder that provides no
' argument type conversion.
' ****************************************************
Class MyCustomBinder
Inherits Binder
Public Overrides Function BindToMethod(bindingAttr As BindingFlags,
match() As MethodBase, ByRef args As Object(),
modIfiers() As ParameterModIfier, culture As CultureInfo,
names() As String, ByRef state As Object) As MethodBase
If match is Nothing Then
Throw New ArgumentNullException("match")
End If
' Arguments are not being reordered.
state = Nothing
' Find a parameter match and return the first method with
' parameters that match the request.
For Each mb As MethodBase in match
Dim parameters() As ParameterInfo = mb.GetParameters()
If ParametersMatch(parameters, args) Then
Return mb
End If
Next mb
Return Nothing
End Function
Public Overrides Function BindToField(bindingAttr As BindingFlags,
match() As FieldInfo, value As Object, culture As CultureInfo) As FieldInfo
If match Is Nothing
Throw New ArgumentNullException("match")
End If
For Each fi As FieldInfo in match
If fi.GetType() = value.GetType() Then
Return fi
End If
Next fi
Return Nothing
End Function
Public Overrides Function SelectMethod(bindingAttr As BindingFlags,
match() As MethodBase, types() As Type,
modifiers() As ParameterModifier) As MethodBase
If match Is Nothing Then
Throw New ArgumentNullException("match")
End If
' Find a parameter match and return the first method with
' parameters that match the request.
For Each mb As MethodBase In match
Dim parameters() As ParameterInfo = mb.GetParameters()
If ParametersMatch(parameters, types) Then
Return mb
End If
Next mb
Return Nothing
End Function
Public Overrides Function SelectProperty(
bindingAttr As BindingFlags, match() As PropertyInfo,
returnType As Type, indexes() As Type,
modIfiers() As ParameterModIfier) As PropertyInfo
If match Is Nothing Then
Throw New ArgumentNullException("match")
End If
For Each pi As PropertyInfo In match
If pi.GetType() = returnType And
ParametersMatch(pi.GetIndexParameters(), indexes) Then
Return pi
End If
Next pi
Return Nothing
End Function
Public Overrides Function ChangeType(
value As Object,
myChangeType As Type,
culture As CultureInfo) As Object
Try
Dim newType As Object
newType = Convert.ChangeType(value, myChangeType)
Return newType
' Throw an InvalidCastException If the conversion cannot
' be done by the Convert.ChangeType method.
Catch
Return Nothing
End Try
End Function
Public Overrides Sub ReorderArgumentArray(ByRef args() As Object, state As Object)
' No operation is needed here because BindToMethod does not
' reorder the args array. The most common implementation
' of this method is shown below.
' ((BinderState)state).args.CopyTo(args, 0)
End Sub
' Returns true only If the type of each object in a matches
' the type of each corresponding object in b.
Private Overloads Function ParametersMatch(a() As ParameterInfo, b() As Object) As Boolean
If a.Length <> b.Length Then
Return false
End If
For i As Integer = 0 To a.Length - 1
If a(i).ParameterType <> b(i).GetType() Then
Return false
End If
Next i
Return true
End Function
' Returns true only If the type of each object in a matches
' the type of each corresponding enTry in b.
Private Overloads Function ParametersMatch(a() As ParameterInfo,
b() As Type) As Boolean
If a.Length <> b.Length Then
Return false
End If
For i As Integer = 0 To a.Length - 1
If a(i).ParameterType <> b(i)
Return false
End If
Next
Return true
End Function
End Class
End Namespace
InvokeMember dan CreateInstance
Gunakan Type.InvokeMember untuk memanggil anggota jenis. Metode CreateInstance
berbagai kelas, seperti Activator.CreateInstance dan Assembly.CreateInstance, adalah bentuk khusus dari InvokeMember
yang membuat instans baru dari jenis yang ditentukan. Kelas Binder
ini digunakan untuk resolusi kelebihan beban dan koersi argumen dalam metode ini.
Contoh berikut menunjukkan tiga kemungkinan kombinasi koersi argumen (konversi jenis) dan pilihan anggota. Dalam Kasus 1, tidak diperlukan paksaan argumen atau pemilihan anggota. Dalam Kasus 2, hanya pilihan anggota yang diperlukan. Dalam Kasus 3, hanya pemasukan argumen yang diperlukan.
public ref class CustomBinderDriver
{
public:
static void Main()
{
Type^ t = CustomBinderDriver::typeid;
CustomBinder^ binder = gcnew CustomBinder();
BindingFlags flags = BindingFlags::InvokeMethod | BindingFlags::Instance |
BindingFlags::Public | BindingFlags::Static;
array<Object^>^ args;
// Case 1. Neither argument coercion nor member selection is needed.
args = gcnew array<Object^> {};
t->InvokeMember("PrintBob", flags, binder, nullptr, args);
// Case 2. Only member selection is needed.
args = gcnew array<Object^> {42};
t->InvokeMember("PrintValue", flags, binder, nullptr, args);
// Case 3. Only argument coercion is needed.
args = gcnew array<Object^> {"5.5"};
t->InvokeMember("PrintNumber", flags, binder, nullptr, args);
}
static void PrintBob()
{
Console::WriteLine("PrintBob");
}
static void PrintValue(long value)
{
Console::WriteLine("PrintValue({0})", value);
}
static void PrintValue(String^ value)
{
Console::WriteLine("PrintValue\"{0}\")", value);
}
static void PrintNumber(double value)
{
Console::WriteLine("PrintNumber ({0})", value);
}
};
int main()
{
CustomBinderDriver::Main();
}
public class CustomBinderDriver
{
public static void Main()
{
Type t = typeof(CustomBinderDriver);
CustomBinder binder = new CustomBinder();
BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Instance |
BindingFlags.Public | BindingFlags.Static;
object[] args;
// Case 1. Neither argument coercion nor member selection is needed.
args = new object[] {};
t.InvokeMember("PrintBob", flags, binder, null, args);
// Case 2. Only member selection is needed.
args = new object[] {42};
t.InvokeMember("PrintValue", flags, binder, null, args);
// Case 3. Only argument coercion is needed.
args = new object[] {"5.5"};
t.InvokeMember("PrintNumber", flags, binder, null, args);
}
public static void PrintBob()
{
Console.WriteLine("PrintBob");
}
public static void PrintValue(long value)
{
Console.WriteLine("PrintValue({0})", value);
}
public static void PrintValue(string value)
{
Console.WriteLine("PrintValue\"{0}\")", value);
}
public static void PrintNumber(double value)
{
Console.WriteLine("PrintNumber ({0})", value);
}
}
Public Class CustomBinderDriver
Public Shared Sub Main()
Dim t As Type = GetType(CustomBinderDriver)
Dim binder As New CustomBinder()
Dim flags As BindingFlags = BindingFlags.InvokeMethod Or BindingFlags.Instance Or
BindingFlags.Public Or BindingFlags.Static
Dim args() As Object
' Case 1. Neither argument coercion nor member selection is needed.
args = New object() {}
t.InvokeMember("PrintBob", flags, binder, Nothing, args)
' Case 2. Only member selection is needed.
args = New object() {42}
t.InvokeMember("PrintValue", flags, binder, Nothing, args)
' Case 3. Only argument coercion is needed.
args = New object() {"5.5"}
t.InvokeMember("PrintNumber", flags, binder, Nothing, args)
End Sub
Public Shared Sub PrintBob()
Console.WriteLine("PrintBob")
End Sub
Public Shared Sub PrintValue(value As Long)
Console.WriteLine("PrintValue ({0})", value)
End Sub
Public Shared Sub PrintValue(value As String)
Console.WriteLine("PrintValue ""{0}"")", value)
End Sub
Public Shared Sub PrintNumber(value As Double)
Console.WriteLine("PrintNumber ({0})", value)
End Sub
End Class
Resolusi kelebihan beban diperlukan ketika lebih dari satu anggota dengan nama yang sama tersedia. Metode Binder.BindToMethod dan Binder.BindToField digunakan untuk menyelesaikan pengikatan ke satu anggota. Binder.BindToMethod
juga menyediakan resolusi properti melalui pengaktor get
properti dan set
.
BindToMethod
MethodBase mengembalikan ke pemanggilan, atau referensi null (Nothing
di Visual Basic) jika tidak ada pemanggilan seperti itu yang dimungkinkan. Nilai MethodBase
pengembalian tidak perlu menjadi salah satu yang terkandung dalam parameter kecocokan, meskipun itu adalah kasus biasa.
Ketika argumen ByRef ada, pemanggil mungkin ingin mendapatkannya kembali. Oleh karena itu, Binder
memungkinkan klien untuk memetakan array argumen kembali ke bentuk aslinya jika BindToMethod
telah memanipulasi array argumen. Untuk melakukan ini, pemanggil harus dijamin bahwa urutan argumen tidak berubah. Saat argumen diteruskan berdasarkan nama, Binder
susun ulang array argumen, dan itulah yang dilihat pemanggil. Untuk informasi selengkapnya, lihat Binder.ReorderArgumentArray .
Kumpulan anggota yang tersedia adalah anggota yang ditentukan dalam jenis atau jenis dasar apa pun. Jika BindingFlags ditentukan, anggota aksesibilitas apa pun dikembalikan dalam set. Jika BindingFlags.NonPublic
tidak ditentukan, pengikat harus menerapkan aturan aksesibilitas. Saat menentukan Public
bendera atau NonPublic
pengikatan, Anda juga harus menentukan Instance
bendera atau Static
pengikatan, atau tidak ada anggota yang akan dikembalikan.
Jika hanya ada satu anggota dari nama yang diberikan, tidak ada panggilan balik yang diperlukan, dan pengikatan dilakukan pada metode tersebut. Kasus 1 dari contoh kode mengilustrasikan poin ini: Hanya satu PrintBob
metode yang tersedia, dan oleh karena itu tidak diperlukan panggilan balik.
Jika ada lebih dari satu anggota dalam set yang tersedia, semua metode ini diteruskan ke BindToMethod
, yang memilih metode yang sesuai dan mengembalikannya. Dalam Kasus 2 dari contoh kode, ada dua metode bernama PrintValue
. Metode yang sesuai dipilih oleh panggilan ke BindToMethod
.
ChangeType melakukan koersi argumen (konversi jenis), yang mengonversi argumen aktual ke jenis argumen formal dari metode yang dipilih. ChangeType
dipanggil untuk setiap argumen bahkan jika jenisnya cocok persis.
Dalam Kasus 3 dari contoh kode, argumen jenis String
aktual dengan nilai "5,5" diteruskan ke metode dengan argumen formal jenis Double
. Agar pemanggilan berhasil, nilai string "5,5" harus dikonversi ke nilai ganda. ChangeType
melakukan konversi ini.
ChangeType
hanya melakukan koersi yang tidak hilang atau melebar, seperti yang ditunjukkan dalam tabel berikut.
Jenis sumber | Jenis target |
---|---|
Jenis apa pun | Jenis dasar tersebut |
Jenis apa pun | Antarmuka yang diimplementasikan |
Char | UInt16, UInt32, Int32, UInt64, Int64, Single, Double |
Byte | Char, UInt16, Int16, UInt32, Int32, UInt64, Int64, Single, Double |
SByte | Int16, Int32, Int64, Single, Double |
UInt16 | UInt32, Int32, UInt64, Int64, Single, Double |
Int16 | Int32, Int64, Single, Double |
UInt32 | UInt64, Int64, Single, Double |
Int32 | Int64, Int64, Single, Double |
UInt64 | Single, Double |
Int64 | Single, Double |
Tunggal | Laju |
Jenis nonreferensi | Jenis referensi |
Kelas Type ini memiliki Get
metode yang menggunakan parameter jenis Binder
untuk menyelesaikan referensi ke anggota tertentu. Type.GetConstructor, Type.GetMethod, dan Type.GetProperty cari anggota tertentu dari jenis saat ini dengan memberikan informasi tanda tangan untuk anggota tersebut. Binder.SelectMethod dan Binder.SelectProperty dipanggil kembali untuk memilih informasi tanda tangan yang diberikan dari metode yang sesuai.