Introduction to Reflection
ู
ูุถูุน ุงูููุงุฑุฏุฉ ุดูู ูู
ู
ุชุน ุฌุฏูุงุ ูู ู
ุชูุฏู
ุดููุฉ ุจุณ ููุจุณุทู ู
ุน ุจุนุถ. ูู
ุง ุชููู
ู ูููุณุ ูุชุชุญู
ุณ ุฌุฏูุง ููุชุญุงูู ุชูุงูู ุฃููุงุฑ ุชุณุชุนู
ูู ูููุงุ ูุฅู ุงูู
ูุถูุน ุฏู powerful ุฌุฏูุง ูุจูุฏููู ุฅู
ูุงููุงุช ุฑููุจุฉ ูุงูุช ุจุชูุชุจ ููุฏ ูู ุงูู .NET.
ูู ุงูุช ุดุบุงู ุญุงูููุง ุนูู ู
ุดุงุฑูุน ุญููููุฉุ ูุงูุช ุณูุงุก ุชุนุฑู ุฃู ู
ุชุนุฑูุดุ ูุงูุช ุจุชุณุชุฎุฏู
ู ุจุดูู ุฃู ุจุขุฎุฑุ ุฃู ุจุชุณุชุฎุฏู
library ูู ุงููู ุจุชุณุชุฎุฏู
ูุ ูุฅูู ุจูู ุฏุงุฎู ุชูุฑูุจูุง ูู ูู ุญุงุฌุฉ.
ู
ูุถูุนูุง ุงูููุงุฑุฏุฉ ุงุณู
ู Reflection.
What is Reflection?
ููู
ุฉ reflection ู
ุนูุงูุง โุงูุนูุงุณโ. ูู
ุง ุจุชูู ูุฏุงู
ุงูู
ุฑุงูุฉ ุจุชุดูู ุงูุนูุงุณ ูููุ ุจุชุดูู ูุดู ูู
ูุงุฎูุฑู ููู ุชูุงุตููู.
ููุณ ุงูููุงู
ุจุงููุณุจุฉ ููููุฏุ ุงูุงูุนูุงุณ ุจูู
ููู ุฅูู ุชุดูู ูุชุทูุน ุนูู ุงูุชูุงุตูู ุงูุฏุงุฎููุฉ ููู Assembly ู
ู ุบูุฑ ู
ุง ูููู ู
ุนุงู ุงูู source code ุจุชุงุนูุ ุฃู ุญุชู ูู ู
ุนุงู ุงูู source code ุจุณ ุนุงูุฒ ุชุนู
ู ุงูููุงู
ุฏู ูู ุงูู run-time.
ูุชููู
ุฃูุชุฑ ูุงุญูุง ู
ุงุดูููุ ุจุณ ุฎูููุง ุงูุฃูู ูุนุฑู ุฅูู ูู ุงูู Assembly ูุฅูู ูู ุฏู ุงูู
ุฏุฎู ุงูุฑุฆูุณู ููู Reflection.
What is an Assembly?
ููู
ุฉ assembly ูู ูุบุงุช ุงูุจุฑู
ุฌุฉ ุนู
ูู
ูุงุ ููู ุงูู .NET ุชุญุฏูุฏูุงุ ุจูุชููู
ุนู ุงูู binary files ุงููู ุจุชุทูุน ู
ู ุนู
ููุฉ ุงูู build ููููุฏ ุจุชุงุนู.
ูู
ุง ุจูุนู
ู build ูุจุฑูุฌูุช ุฌุฏูุฏุ ุจููุงูู ูู ุงูู output folder ู
ููุงุช ุงูุงู
ุชุฏุงุฏ ุจุชุงุนูุง .dll ู .exe. ูู ู
ูู ู
ู ุฏูู ุจูููู ุนููู Assembly. ุจู
ุง ุฅููุง ุดุบุงููู .NET Coreุ ุฎูููุง ูุฑูุฒ ุฃูุชุฑ ุนูู ุงูู DLL.
ูุงูู Assembly ูู .NET ูู ู
ูู ุงูู DLL ุงููู ุจูุฎุฑุฌ ูู
ุง ุชุนู
ู build ููุจุฑูุฌูุช ุจุชุงุนู.
ุงูู Assembly ุฏู ุจูููู ุดุงูู ุญุงุฌุงุช ูุชูุฑุ ู
ููุง:
- ุงูู Metadata: ุฏู ู
ุนููู
ุงุช ุนู ุงูู
Assemblyููุณู ูู ุญุชููุงุชูุ ุฒู ุงุณู ุงููAssemblyุ ุงููversionุจุชุงุนูุ ุงููlocationุ ูุชูุงุตูู ุชุงููุฉ ูุชูุฑ. - ุงูู Intermediate Language (IL): ุงุชููู
ูุง ุนู ุงูู
ILูุจู ูุฏู. ุฏู ุงููุบุฉ ุงููุณูุทุฉ ุงููู ุงูููุฏ ุจุชุงุนู ุจูุชุฑุฌู ูููุง ููุช ุงููcompilation. ุงูููุฏ ู ุด ุจูุชุญูู ููmachine languageู ุจุงุดุฑุฉุ ูุฃุ ุจูุชุญูู ุงูุฃูู ููILุ ูุจุนุฏ ูุฏู ูู ุงููrun-timeุงููILุจูุชุญูู ููmachine code. - ุงูู Embedded Resources: ุฏู ู
ููุงุช ุงูุช ุจุชุฏู
ุฌูุง ู
ุน ุงูู
Assemblyุจุชุงุนู ูู ุญุจูุช.
ุชุนุงููุง ูุดูู ุงูููุงู ุฏู ุจูุชู ุฅุฒุงู ุจุงูุชูุตูู.
Getting Started with Reflection
ุนุดุงู ูุจุฏุฃ ูุชุนุงู
ู ู
ุน ุงูู Reflectionุ ุฃูู ุญุงุฌุฉ ุจูุนู
ููุง ูู import ููู namespace ุงููู ุงุณู
ู System.Reflection.
using System.Reflection;ุฏู ุงููู ููู ูู ุงูุฃุฏูุงุช ุงููู ููุญุชุงุฌูุง. ุจุนุฏ ูุฏูุ ุฃูุง ุนุงูุฒ ุฃูุตู ุฃู ุขุฎุฏ reference ููู Assembly.
ุงุญูุง ุงุชูููุง ุฅู ุงูู Assembly ูู ู
ูู ุงูู DLL. ูู
ุง ุจุนู
ู run ููุจุฑูุฌูุช ุจุชุงุนูุ ุนู
ููุฉ ุงูู run ุจุชุนู
ู build ุงูุฃููุ ูุงูู compiler ุจูุทูุน ุงูู Assemblyุ ูุจุนุฏูู ุงูู debugger ุจูุงุฎุฏ ุงูู Assembly ุฏู ููุนู
ูู attach ุนุดุงู ุชูุฏุฑ ุชุนู
ู debug.
ูุงูุจุฑูุฌูุช ุจุชุงุนู ุงููู ูู CsharpAdvancedReflection ูู
ุง ุฃุนู
ูู run ููุช ุชุดุบููู ุจูู ุงุณู
ู Assembly.
ุนุดุงู ุฃูุตู ููุ ููู class ุงุณู
ู Assembly ุฌูุงู ุดููุฉ methods ุฒู:
GetEntryAssembly()GetExecutingAssembly()GetCallingAssembly()
ุฎูููุง ุฏูููุชู ูู GetExecutingAssembly(). ุงูู method ุฏู ุจุชุฑุฌุนูู reference ููู Assembly ุงููู ููู ุงูููุฏ ุงููู ุจูุชููุฐ ุญุงูููุง. ูุนูู ุงูุณุทุฑ ุงููู ุจุชูุงุฏู ููู ุงูู method ุฏูุ ููุฑุฌุนูู ุงูู Assembly ุจุชุงุน ุงูุจุฑูุฌูุช ุงููู ุงูุณุทุฑ ุฏู ู
ูุชูุจ ููู.
// Get a reference to the currently executing assembly
Assembly assembly = Assembly.GetExecutingAssembly();ุชุนุงููุง ูุดูู ุฅูู ุงูุชูุงุตูู ุงููู ู
ู
ูู ูุนุฑููุง ุนู ุงูู Assembly.
// Print the full name of the assembly
Console.WriteLine($"Assembly Name: {assembly.FullName}");
// Print the location (path) of the assembly file
Console.WriteLine($"Assembly Location: {assembly.Location}");ูู ุง ูุดุบู ุงูููุฏ ุฏู ููุดูู ุงููุชูุฌุฉ:
Assembly Name: CsharpAdvancedReflection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Assembly Location: C:\...\CsharpAdvancedReflection.dll
ุงูู FullName ุจูุญุชูู ุนูู ูุฐุง ู
ุนููู
ุฉ: ุงูุงุณู
ุ ุงูู Versionุ ุงูู Cultureุ ูุงูู PublicKeyToken.
ุทุจ ูู ุนุงูุฒ ุชูุตู ุงูู
ุนููู
ุงุช ุฏู ูุชุงุฎุฏ ูู ุญุงุฌุฉ ููุญุฏูุงุ ููู method ุงุณู
ูุง GetName().
// Get an AssemblyName object with detailed information
AssemblyName assemblyName = assembly.GetName();
Console.WriteLine($"Name: {assemblyName.Name}");
Console.WriteLine($"Version: {assemblyName.Version}");ุงูู method ุฏู ุจุชุฑุฌุน object ู
ู ููุน AssemblyName ุฌูุงู ุงูุชูุงุตูู ุฏู ู
ุชูุตูุฉ. ููู ุนู
ูุช assemblyName.ToString() ููุฑุฌุนูู ููุณ ุงูู FullName ุงููู ุดููุงู ููู.
Entry vs. Calling vs. Executing Assembly
ุนุดุงู ูููู
ุงููุฑู ุจูู ุงูู methods ุงูู
ุฎุชููุฉุ ููุนู
ู setup ุจุณูุท:
- ููุถูู
class libraryุจุฑูุฌูุช ุฌุฏูุฏ ููุณู ููMyFirstExtension. - ููุถูู
class libraryุชุงูู ููุณู ููMySecondExtension.
ุงููุฏู ู
ููู
ุฅููุง ููุถุญ ุงููุฑู ุจูู GetEntryAssembly, GetCallingAssembly, ู GetExecutingAssembly.
ููุนู
ู reference ูุงูุชุงูู:
- ุงูุจุฑูุฌูุช ุงูุฑุฆูุณู (
CsharpAdvancedReflection) ููุงุฎุฏreferenceู ูMyFirstExtension. - ุงูุจุฑูุฌูุช
MyFirstExtensionููุงุฎุฏreferenceู ูMySecondExtension.
graph LR MainProject(CsharpAdvancedReflection) --> FirstExt(MyFirstExtension); FirstExt --> SecondExt(MySecondExtension);
ูู MyFirstExtensionุ ููุนู
ู class ุงุณู
ู ReflectionDemo ูููู method ุงุณู
ูุง PrintAssemblyDetails.
ูู MySecondExtensionุ ููุนู
ู class ุงุณู
ู ReflectionDemo2 ูููู ููุณ ุงูู method.
ุงูู method ุงููู ูู ReflectionDemo ูุชูุงุฏู ุนูู ุงูู method ุงููู ูู ReflectionDemo2.
// In MyFirstExtension -> ReflectionDemo.cs
public static class ReflectionDemo
{
public static void PrintAssemblyDetails()
{
// Call the method in the second extension
MySecondExtension.ReflectionDemo2.PrintAssemblyDetails();
}
}ููู ุงูุจุฑูุฌูุช ุงูุฑุฆูุณูุ ูููุงุฏู ุนูู ุงูู method ุงููู ูู MyFirstExtension.
// In Main Project -> Program.cs
MyFirstExtension.ReflectionDemo.PrintAssemblyDetails();ุงูู call stack ู
ุงุดู ุฅุฒุงูุ
ุงูู CsharpAdvancedReflection ุจููุงุฏู MyFirstExtension ุงููู ุจุฏูุฑู ุจููุงุฏู MySecondExtension.
ุฏูููุชูุ ุฌูู ุงูู method ุงูููุงุฆูุฉ ูู ReflectionDemo2 ููุทุจุน ุจูุงูุงุช ุงูู Assemblies ุงูุชูุงุชุฉ.
// In MySecondExtension -> ReflectionDemo2.cs
public static void PrintAssemblyDetails()
{
var entryAssembly = Assembly.GetEntryAssembly();
var callingAssembly = Assembly.GetCallingAssembly();
var executingAssembly = Assembly.GetExecutingAssembly();
Console.WriteLine($"Entry Assembly: {entryAssembly.GetName().Name}");
Console.WriteLine($"Calling Assembly: {callingAssembly.GetName().Name}");
Console.WriteLine($"Executing Assembly: {executingAssembly.GetName().Name}");
}ูู ุง ูุดุบู ุงูููุฏุ ุงููุงุชุฌ ููููู:
Entry Assembly: CsharpAdvancedReflection
Calling Assembly: MyFirstExtension
Executing Assembly: MySecondExtension
ูุฏู ููู ูุง ุงููุฑู:
- ุงูู Entry Assembly: ูู ุงูู
Assemblyุงููู ุจุฏุฃ ุชูููุฐ ุงูุฃุจูููุดู (ู ูู ุงููEXEุนุงุฏุฉู). - ุงูู Calling Assembly: ูู ุงูู
Assemblyุงููู ูุงุฏู ุนูู ุงููmethodุงููู ุจุชุชููุฐ ุญุงูููุง. ูู ุญุงูุชูุงุMyFirstExtensionูู ุงููู ูุงุฏู ุนููPrintAssemblyDetailsุงููู ููMySecondExtension. - ุงูู Executing Assembly: ูู ุงูู
Assemblyุงููู ููู ุงูููุฏ ุงููู ุจูุชููุฐ ุญุงูููุง.
Resources
Embedded Resources
ููููู ููุงู
ูุง ุนู ุงูู Assembly ุจู
ูุถูุน ุงูู Resources. ุงูุชุฑุถ ุฅู ุงูุจุฑูุฌูุช ุจุชุงุนู ู
ุญุชุงุฌ ูุฏุนู
ุงูุชุฑุฌู
ุฉ. ุฏู ู
ุนูุงู ุฅูู ู
ุญุชุงุฌ dictionary ููู ูุบุฉ. ุงูู
ููุงุช ุฏู ุงูู
ูุฑูุถ ุชููู ู
ูุฌูุฏุฉ ู
ุน ุงูุฃุจูููุดู ุจุชุงุนู ุนุดุงู ุชูุฑุงูุง ูู ุงูู run-time.
ุจุณ ููู ู ุดููุฉ: ูู ุงูู ูู ู ูุฌูุฏ ุฌูุจ ุงูุฃุจูููุดูุ ุงูููุฒุฑ ููุฏุฑ ููุชุญู ููุนุฏู ูููุ ูุงูุช ู ุด ุนุงูุฒ ูุฏู. ุนุงูุฒ ุชุญู ู ู ููุงุช ุงูุชุฑุฌู ุฉ ุฏู.
ุฃุญุฏ ุงูุญููู ูู ุงูู Embedded Resources. ุฅุฒุงูุ
ููุถูู ูููุฏุฑ ุฌุฏูุฏ ูู ุงูุจุฑูุฌูุช ุงูุฑุฆูุณู ููุณู
ูู Resourcesุ ูุฌูุงู ููุถูู ู
ูู ุชูุณุช ar.txt.
ูู
ุง ุชุฎุชุงุฑ ุงูู
ูู ุฏูุ ูุชูุงูู ูู ุงูู Properties ุจุชุงุนุชู ุฎุงุตูุชูู ู
ูู
ูู:
- ุงูู Copy to Output Directory: ุฏู ุจุชุญุฏุฏ ูู ุงูู
ูู ููุชูุณุฎ ูููููุฏุฑ ุจุชุงุน ุงูู
buildููุง ูุฃ. ุงูููู ุฉ ุงูุงูุชุฑุงุถูุฉDo not copy. ูู ุฎููุชูุงCopy alwaysุ ุงูู ูู ููุชูุณุฎ ุฌูุจ ุงููDLLุจุชุงุนู. ุจุณ ุฏู ู ุด ุงููู ุงุญูุง ุนุงูุฒูููุ ูุฅู ุงูููุฒุฑ ูููุฏุฑ ูุดููู. - ุงูู Build Action: ุฏู ุจุชุญุฏุฏ ุฅูู ุงูุฅุฌุฑุงุก ุงููู ููุชุงุฎุฏ ู
ุน ุงูู
ูู ุฏู ููุช ุงูู
build. ุงูููู ุฉ ุงูุงูุชุฑุงุถูุฉNone.
ุงููู ููู
ูุง ููุง ูู ููู
ุฉ Embedded Resource. ูู ุงุฎุชุฑุชูุง ูุนู
ูุช buildุ ุงูู
ูู ู
ุด ููุธูุฑ ูู ุงูู output folderุ ูููู ููููู ุงุชุฏู
ุฌ ุฌูู ู
ูู ุงูู DLL ููุณู.
ูู ุงุณุชุฎุฏู
ูุง ุฃุฏุงุฉ ุฒู JetBrains dotPeek ุนุดุงู ููุชุญ ุงูู DLLุ ูููุงูู ูููุฏุฑ ุงุณู
ู Resources ุธูุฑ ุฌูู ุงูู Assemblyุ ูุฌูุงู ุงูู
ูู ุจุชุงุนูุง.
ุงูุงุณู
ุจุชุงุน ุงูู resource ุฏู ู
ูู
ุฌุฏูุงุ ูุฅูู ูุชุณุชุฎุฏู
ู ุนุดุงู ุชูุตู ููู
ูู ูู ุงูู run-time. ุงูุงุณู
ุจูููู ุจุงูุตูุบุฉ ุฏู:
ProjectName.FolderName.FileName
ููู ุญุงูุชูุง ููููู: CsharpAdvancedReflection.Resources.ar.txt.
ู
ูุญูุธุฉ: ุงูุงุณู
ุฏู case-sensitiveุ ูุนูู ุงูุญุฑูู ุงููุงุจูุชุงู ูุงูุณู
ูู ุจุชูุฑู.
Reading Embedded Resources
ุฏูููุชู ุฃูุง ุนุงูุฒ ุฃูุฑุฃ ู
ุญุชููุงุช ุงูู
ูู ุฏู ูุฃุทุจุนูุง ูู ุงูู Console.
ูุงุฒู
ููุฑุฃ ุงูู resource ู
ู ููุณ ุงูู Assembly ุงููู ูู ุฌูุงู.
// Get the current assembly
Assembly assembly = Assembly.GetExecutingAssembly();
// Define the resource name
string resourceName = "CsharpAdvancedReflection.Resources.ar.txt";
// Get the resource as a stream
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
Console.WriteLine("Resource not found!");
return;
}
Console.WriteLine("Resource found!");
// Use a StreamReader to read the content
using (StreamReader reader = new StreamReader(stream))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
}ุงูู ูู ุงูู Streamุ ุจุงุฎุชุตุงุฑ ุดุฏูุฏุ ูู ุขููุฉ ุจุชู
ููู ู
ู ูุฑุงุกุฉ ููุชุงุจุฉ ุงูุจูุงูุงุช ูู ุฃู ู
ูุงู (ู
ููุ ู
ูู
ูุฑูุ ุฏุงุชุงุจูุฒุ ุฅูุฎ). ุงูู method ุงููู ุงุณู
ูุง GetManifestResourceStream ุจุชุฑุฌุนูู stream object ููู
ูู ุงููู ุญุฏุฏุชู.
ุงูู stream ุฏู ุจูุฏููู access ุนูู ุงูู Bytes ุจุชุงุนุฉ ุงูู
ูู. ูู ู
ูู ูู ุงูุขุฎุฑ ูู ุนุจุงุฑุฉ ุนู ุดููุฉ bytes ุฌูุจ ุจุนุถ. ุจููุฏุฑ ููุฑุฃ ุงูู bytes ุฏู ููุญูููุง ูู characters.
ูู ุงูููุฏ ุงููู ูููุ ุงุณุชุฎุฏู
ูุง StreamReader ุนุดุงู ูุณูู ุนูููุง ุนู
ููุฉ ุงููุฑุงุกุฉ ูุชุญููู ุงูู bytes ููุต.
ูู ุบูุฑูุง ุญุฑู ูุงุญุฏ ูู ุงุณู
ุงูู resource (ู
ุซูุงู ุฎูููุงู ูุงุจูุชุงู ููู ุณู
ูู)ุ ุงูู stream ููุฑุฌุน null ููุชุธูุฑ ุฑุณุงูุฉ โResource not found!โ.
ุฏู ูุฏู ุงูุฌุฒุก ุงูุฃูู ู
ู ุงูููุฏูู. ุดูููุง ุฅูู ูู ุงูู Assemblyุ ูุงููุฑู ุจูู ุทุฑู ุงูุญุตูู ุนูููุ ูุฅุฒุงู ูุนู
ู embedded resource ูููุฑุฃู. ูู ุงูุฌุฒุก ุงูุฌุงูุ ููุฏุฎู ูู ุนู
ู ุงูู Reflection ููุดูู ุงูููุฉ ุงูุญููููุฉ ุงููู ุจูุฏููุง ูููุง.
Inspecting Types and Dynamic Invocation
ููููุง ุฅู ุงูู Assembly ูู ุจูุงุจุฉ ุงููุตุฑ ุงููุจูุฑุฉ. ุงูู Assembly ุฏู ูู ุงูุจุฑูุฌูุช ุจุชุงุนู ุจุนุฏ ู
ุง ูุชุนู
ูู build.
ุฌูู ุงูุจุฑูุฌูุช ุฏู ููู ุฅููุ ููู types ุฒู classes, interfaces, structs. ูุฌูู ูู type ููู methods, properties, fields, ู events.
ูุจุนุฏ ู
ุง ุฏุฎููุง ู
ู ุงูุจูุงุจุฉ ุงููุจูุฑุฉ (Assembly)ุ ูุฏุงู
ูุง ุฏูููุชู ุฃุจูุงุจ ุงูุบุฑู ุงููู ุฌูู ุงููุตุฑุ ูุงููู ูู ุงูู Types. ุนุดุงู ุฃูุฏุฑ ุฃุฏุฎู ุฃู ุบุฑูุฉุ ู
ุญุชุงุฌ ุฃูุตู ููู Type ุจุชุงุนูุง ุงูุฃูู.
Getting a Type Object
ุงุชููู
ูุง ูุจู ูุฏู ุฅู ูู ุงูุฃููุงุน ูู ุงูู .NET ุจุชูุฑุซ ู
ู parent ูุงุญุฏ ุฑุฆูุณู ูู Object. ููู ุงูู Object class ุฏูุ ููู method ุงุณู
ูุง GetType().
object obj = new object();
Type objectType = obj.GetType();ุงูู method ุฏู ุจุชุฑุฌุน object ู
ู ููุน ุงุณู
ู Type. ุงูู Type ุฏู ูู ุจุงุจ ุงูุบุฑูุฉ ุงููู ูู
ุง ุชูุชุญู ูุชูุฏุฑ ุชุดูู ูู ุงููููุฒ ุงููู ุฌูุงูุง.
ูุงุฒู
ุชุญุท ูู ุฏู
ุงุบู ุฅููุง ูู ุฏู ุจูุชุนุงู
ู ู
ุน assembly ูููุฏ ูู ุงูู run-timeุ ู
ุด ูู ุงูู compile-time. ูุนูู ุฅููุ ูุนูู ุชุฎูู ุฅูู ู
ุด ู
ุนุงู reference ููู assembly ุฏู ุฃุตููุงุ ูู
ุน ุฐูู ุจุชูุฏุฑ ุชุชุนุงู
ู ู
ุนุงู. ูู ุฏู ุฏูุฑ ุงูู Reflection.
ุทูุจุ ุฅุฒุงู ููุตู ููู Type ุฏูุ
ุงูู Assembly ููุณู ุฌูุงู method ุงุณู
ูุง GetTypes()ุ ูุฏู ุจุชุฑุฌุนูู ูู ุงูู types ุงููู ู
ุชุนุฑูุฉ ุฌูุงู.
public class Employee { }
public class Product { }
// ... in Main method
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
foreach (var type in types)
{
Console.WriteLine($"Type Name: {type.FullName}");
}ููุง ุนู
ููุง loop ุนูู ูู ุงูู types ุงููู ูู ุงูู Assembly ุงูุญุงูู.
ู
ู ุงูู Type object ุฏูุ ุชูุฏุฑ ุชุนุฑู ูู ุชูุงุตููู:
foreach (var type in types)
{
Console.WriteLine($"Name: {type.Name}");
Console.WriteLine($"Is Public: {type.IsPublic}");
// Use ?. to avoid null error if it has no base
Console.WriteLine($"Base Type: {type.BaseType?.Name}");
Console.WriteLine("----------------");
}ุจุงูุทุฑููุฉ ุฏูุ ุจุชูุฏุฑ ุชุนุฑู ุงุณู
ุงูู Typeุ ูู public ููุง ูุฃุ ูุจููุฑุซ ู
ู ู
ูู (BaseType)ุ ููู ูู sealed ุฃู genericุ ููู ุญุงุฌุฉ ุชุงููุฉ. ุฏู ุงููู ุจูุณู
ููุง ุงูู Metadata ุจุชุงุนุฉ ุงูู Type.
ููู method ุชุงููุฉ ุงุณู
ูุง GetExportedTypes() ูุฏู ุจุชุฑุฌุน ุงูู public types ุจุณุ ุนูู ุนูุณ GetTypes() ุงููู ุจุชุฑุฌุน ููู.
ููู ุทุฑู ุชุงููุฉ ุนุดุงู ุชุฌูุจ ุงูู Type:
- ูู ู
ุนุงู
variableุ ู ู ูู ุชุณุชุฎุฏูvariable.GetType(). - ูู ุนุงูุฒ
Typeู ุนูู ุจุงุณู ูุ ู ู ูู ุชุณุชุฎุฏูtypeof()keyword.
Type stringType = typeof(string);
Type intType = typeof(int);Inspecting Type Members
ุฏูููุชู ุจุนุฏ ู
ุง ูุชุญูุง ุจุงุจ ุงูุบุฑูุฉ (Type)ุ ุนุงูุฒูู ูุดูู ุงููููุฒ ุงููู ุฌูุงูุง. ุงูู Type class ููู method ุงุณู
ูุง GetMembers()ุ ูุฏู ุจุชุฑุฌุน ูู ุงูู code members ุงููู ุฌูู ุงูู Type ุฏู (ุณูุงุก method, property, field, event, constructor, ุฃู ุญุงุฌุฉ).
Type dateTimeType = typeof(DateTime);
MemberInfo[] members = dateTimeType.GetMembers();
foreach (var member in members)
{
Console.WriteLine($"Name: {member.Name}, Member Type: {member.MemberType}");
}ูุชูุงุญุธ ุฅู methods ุฒู Parse ุจุชุชูุฑุฑ ูุฐุง ู
ุฑุฉ. ุฏู ุจุณุจุจ ุงูู Method Overloadingุ ูู overload ุจูุนุชุจุฑ member ู
ููุตู.
ุงูู GetMembers() ุจุชุฑุฌุน ูู ุงูู members ุจุบุถ ุงููุธุฑ ูู static ููุง instance.
Filtering Members with BindingFlags
ูู ุนุงูุฒ ุชููุชุฑ ุงููุชุงูุฌุ ููู overload ุชุงูู ููู method ุฏู ุจูุงุฎุฏ enum ุงุณู
ู BindingFlags. ุฏู ุนุจุงุฑุฉ ุนู flags ุจุชุญุฏุฏ ุจููุง ุฅูู ุงููู ุงูุช ุนุงูุฒู ุจุงูุธุจุท.
// Get only PUBLIC INSTANCE members
var instanceMembers = dateTimeType.GetMembers(BindingFlags.Public | BindingFlags.Instance);
// Get only PUBLIC STATIC members
var staticMembers = dateTimeType.GetMembers(BindingFlags.Public | BindingFlags.Static);
// Get NON-PUBLIC STATIC members (private, internal, etc.)
var nonPublicStaticMembers = dateTimeType.GetMembers(BindingFlags.NonPublic | BindingFlags.Static);ูุงุญุธ ุฅููุง ุจูุณุชุฎุฏู
| (single pipe)ุ ูุฏู ุงูู bitwise OR operator ุงููู ุจูุณุชุฎุฏู
ู ุนุดุงู ูุฏู
ุฌ ุงูู flags ู
ุน ุจุนุถ.
ุจุงูุทุฑููุฉ ุฏูุ ุชูุฏุฑ ุชุดูู ุญุชู ุงูู private members ุงููู ูู ุงูุนุงุฏู ู
ุด ุจุชูุฏุฑ ุชูุตููุง. ูุดููุฉ ูููุนุฑู ุฅุฒุงู ูููุฐ private method ูู
ุงู!
ูู ุนุงูุฒ ุชุฌูุจ ููุน ู
ุนูู ู
ู ุงูู membersุ ููู methods ู
ุฎุตุตุฉ ุจุชุณูู ุนููู ุงูู
ูุถูุน:
GetMethods()GetProperties()GetFields()GetConstructors()
ู
ุซูุงูุ ุนุดุงู ูุนุฑู ูู ุงูู property ุฏู read-only ููุง ูุฃุ ู
ู
ูู ูุดูู ูู ูููุง set method ููุง ูุฃ.
var properties = dateTimeType.GetProperties();
foreach (var prop in properties)
{
bool isReadOnly = !prop.CanWrite;
Console.WriteLine($"Property: {prop.Name}, Is Read-Only: {isReadOnly}");
}Getting Method Parameters
ุจุนุฏ ู
ุง ุฌุจูุง ุงูู methodsุ ู
ู
ูู ูู
ุงู ูุนุฑู ุฅูู ุงูู parameters ุงููู ูู method ุจุชุงุฎุฏูุง.
// Get a specific method by name
MethodInfo addDaysMethod = dateTimeType.GetMethod("AddDays");
if (addDaysMethod != null)
{
// Get its parameters
ParameterInfo[] parameters = addDaysMethod.GetParameters();
foreach (var param in parameters)
{
Console.WriteLine($"Parameter Name: {param.Name}, Type: {param.ParameterType.Name}");
}
}ุจุงูุทุฑููุฉ ุฏูุ ุจุชูุฏุฑ ุชุดุฑุญ ุงูู DLL ูุชุนุฑู ูู ุชูุงุตููู ู
ู ุบูุฑ ู
ุง ูููู ู
ุนุงู ุงูุณูุฑุณ ููุฏ.
Invoking Methods Dynamically
ูุญุฏ ููุง ุฅุญูุง ุจููุฑุฃ ู
ุนููู
ุงุช ุจุณ. ุงูุงุณุชูุงุฏุฉ ุงูุฃูุจุฑ ู
ู ุงูู Reflection ูู ุฅููุง ููุฏุฑ ูุชูุงุนู ู
ุน ุงูู Type ุฏูุ ูุนูู ูููุฐ ุงูู methods ุจุชุงุนุชู ุจุดูู ุฏููุงู
ููู ุจุงุณุชุฎุฏุงู
method ุงุณู
ูุง Invoke().
Invoking a Static Method
ุงูู static method ู
ุด ู
ุญุชุงุฌุฉ instance ู
ู ุงูู class ุนุดุงู ุชุชููุฐ.
Type mathType = typeof(Math);
MethodInfo minMethod = mathType.GetMethod("Min", new Type[] { typeof(int), typeof(int) });
// Parameters for the method
object[] parameters = { 5, 10 };
// Invoke the static method. First argument is null because it's static.
object result = minMethod.Invoke(null, parameters);
Console.WriteLine($"The minimum is: {result}"); // Output: 5ุงูู Invoke method ุจุชุงุฎุฏ 2 parameters:
- ุงูู
instanceุงููู ูุชููุฐ ุนููู ุงููmethod. ูู ุญุงูุฉ ุงููstatic methodุ ุจูุจุนุชnull. - ุงูู
Array of objectsุจูู ุซู ุงููparametersุงููู ุงููmethodู ุญุชุงุฌุงูุง.
Invoking an Instance Method
ุงูู instance method ูุงุฒู
ุชุชููุฐ ุนูู object ู
ุนูู.
DateTime today = DateTime.Now;
Type dateTimeType = typeof(DateTime);
MethodInfo addDaysMethod = dateTimeType.GetMethod("AddDays");
// Parameters for the AddDays method
object[] parameters = { 10.0 }; // Add 10 days
// Invoke the method on the 'today' instance
// Note: DateTime is immutable, so AddDays returns a new instance
object newDate = addDaysMethod.Invoke(today, parameters);
Console.WriteLine($"Original Date: {today}");
Console.WriteLine($"New Date: {newDate}");ููุง ุจุนุชูุง ุงูู today object ูุฃูู parameter ููู Invoke ุนุดุงู ูุนุฑู ูููุฐ ุงูู method ุฏู ุนูู ู
ูู.
Practical Use Cases for Reflection
ุฏูููุชู ุงูุตูุฑุฉ ูุชุจุฏุฃ ุชูุถุญ ุฃูุชุฑ ูู ุง ูุดูู ุฃู ุซูุฉ ุนู ููุฉ.
Use Case 1: Building a Plugin System
ุจุฑุงู
ุฌ ุฒู Visual Studio ู VS Code ุจุชุณุชุฎุฏู
extensions ุนุดุงู ุชุฒูุฏ features. ุงูู extensions ุฏู ุจุชุดุชุบู ุฅุฒุงูุ ุจุงูู Reflection.
ุงูููุฑุฉ ุฅู ุงูุฃุจูููุดู ุงูุฃุณุงุณู ุจูุนู
ู scan ููููุฏุฑ ู
ุนููุ ููุงูู ููู ู
ููุงุช DLL (ุงูู plugins)ุ ููุณุชุฎุฏู
ุงูู Reflection ุนุดุงู ูุญู
ู ุงูู assemblies ุฏู ูู ุงูู run-timeุ ูุจุนุฏูู ูุจุฏุฃ ูุดูู ุฅูู ุงูู classes ูุงูู methods ุงููู ุฌูุงูุง ููููุฐูุง.
sequenceDiagram participant App as Main App participant FS as File System participant Reflector as Reflection participant Plugin as Plugin.dll App->>FS: Scan "Plugins" folder for DLLs FS-->>App: Found Plugin.dll App->>Reflector: Assembly.LoadFrom("Plugin.dll") Reflector-->>App: Loaded Assembly App->>Reflector: assembly.GetType("Plugin.EntryPoint") Reflector-->>App: Found Type App->>Reflector: type.GetMethod("Initialize") Reflector-->>App: Found Method App->>Plugin: method.Invoke() Plugin-->>App: Plugin Initialized!
ุจุงูููุฏุ ุงูู ูุถูุน ู ู ูู ูุจูู ูุฏู:
string pluginsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Extensions");
string[] pluginFiles = Directory.GetFiles(pluginsPath, "*.dll");
foreach (var file in pluginFiles)
{
// 1. Load the assembly
Assembly pluginAssembly = Assembly.LoadFrom(file);
// 2. Find the entry point type (assuming a convention)
// The full name is needed: Namespace.TypeName
string typeName = $"{pluginAssembly.GetName().Name}.EntryPoint";
Type entryPointType = pluginAssembly.GetType(typeName);
if (entryPointType != null)
{
// 3. Find the initialization method
MethodInfo initializeMethod = entryPointType.GetMethod("Initialize");
if (initializeMethod != null)
{
// 4. Invoke the method
initializeMethod.Invoke(null, null); // Assuming it's a static method with no parameters
}
}
}ุจูุฏูุ ุฃูุช ุนู
ูุช ุณูุณุชู
ุจููุฑุฃ extensions ููุดุบููุง ูู ุงูู run-time ู
ู ุบูุฑ ู
ุง ุชููู ุนุงุฑู ุนููุง ุฃู ุญุงุฌุฉ ููุช ุงูู compile-time.
Use Case 2: Dynamic Object Mapping
ุนู
ููุฉ ูุณุฎ ุงูุฏุงุชุง ู
ู object ูู object ุชุงูู (ุฎุตูุตูุง ู
ู ุฃููุงุน ู
ุฎุชููุฉ) ุงุณู
ูุง mapping. ุงูู
ูุชุจุงุช ุงูู
ุดููุฑุฉ ุฒู AutoMapper ุจุชุณุชุฎุฏู
ุงูู Reflection ุจูุซุงูุฉ.
ููุฏุฑ ูุนู
ู mapper ุจุณูุท ุฌุฏูุง ุจุงูู Reflection:
public static void MapProperties(object source, object destination)
{
Type sourceType = source.GetType();
Type destType = destination.GetType();
PropertyInfo[] sourceProps = sourceType.GetProperties();
foreach (var sourceProp in sourceProps)
{
// Find a property with the same name in the destination object
PropertyInfo destProp = destType.GetProperty(sourceProp.Name);
// Check if the destination property exists and is writable
if (destProp != null && destProp.CanWrite)
{
// Get value from source and set it on destination
object value = sourceProp.GetValue(source);
destProp.SetValue(destination, value);
}
}
}ุงูู method ุฏูุ ูู 3 ุณุทูุฑ logicุ ุจุชูุฏุฑ ุชูุณุฎ ุงูููู
ุจูู ุฃู ุงุชููู objects ุทุงูู
ุง ุฃุณู
ุงุก ุงูู properties ู
ุชุดุงุจูุฉุ ุญุชู ูู ูุงููุง ู
ู ุฃููุงุน ู
ุฎุชููุฉ ุชู
ุงู
ูุง. ุฏู ู
ุซุงู ูุงุถุญ ุฌุฏูุง ุนูู ููุฉ ูู
ุฑููุฉ ุงูู Reflection.
Conclusion
ุงูู Reflection ู
ุณุชุฎุฏู
ูู ุญุงุฌุงุช ูุชูุฑ ุฌุฏูุง ูู ุนุงูู
ุงูู .NET:
- ุงูู Dependency Injection (DI) Containers: ุจุชุณุชุฎุฏู
ู ุนุดุงู ุชูุชุดู ุงูู
servicesูุชุนู ููุงinstantiate. - ุงูู Object-Relational Mappers (ORMs): ุฒู Entity Frameworkุ ุจูุณุชุฎุฏู
ู ุนุดุงู ูุนู
ู
mapููุฏุงุชุง ุงููู ุฌุงูุฉ ู ู ุงูุฏุงุชุงุจูุฒ ูููC# objects. - ุงูู Serialization Libraries: ุฒู
Newtonsoft.Jsonุ ุจุชุณุชุฎุฏู ู ุนุดุงู ุชูุฑุฃ ุงููpropertiesูุชุญูู ุงููobjectููJSONูุงูุนูุณ. - ุงูู Unit Testing Frameworks: ุจุชุณุชุฎุฏู
ู ุนุดุงู ุชูุชุดู ุงูู
Test methodsูุชุดุบููุง.
A Note on Attributes
ุขุฎุฑ ุญุงุฌุฉ ุงูู Attributes. ูู ุนุจุงุฑุฉ ุนู โุนูุงู
ุฉโ ุฃู metadata ุฅุถุงููุฉ ุจุชุญุทูุง ุนูู ุงูููุฏ ุจุชุงุนู (ุฒู class ุฃู method).
[Serializable]
public class MyData
{
[Required]
public string Name { get; set; }
}ุงูู attributes ุฏู ูู ุญุฏ ุฐุงุชูุง ู
ุด ุจุชุนู
ู ุญุงุฌุฉ. ูู ู
ุฌุฑุฏ ู
ุนููู
ุงุช. ุงูู Reflection ูู ุงูุฃุฏุงุฉ ุงููู ุจุชุฎููู ุชูุฑุฃ ุงูู metadata ุฏู ูู ุงูู run-time ูุชุงุฎุฏ action ุจูุงุกู ุนูููุง.
// Check if a type has a specific attribute
bool isSerializable = typeof(MyData).IsDefined(typeof(SerializableAttribute), false);ุงูู Reflection ู
ูุถูุน ููู ุฌุฏูุงุ ูููู
ู ุจููุชุญูู ุฃุจูุงุจ ูุชูุฑ ูุจูุฎููู ุชููู
ุฅุฒุงู ุงูุฃุฏูุงุช ูุงูู
ูุชุจุงุช ุงููู ุจุชุณุชุฎุฏู
ูุง ูู ููู
ุดุบุงูุฉ ู
ู ุฌูู.