در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

آموزش Reflection در برنامه های دات نت قسمت 2 : Meta Data Viewer

در قسمت اول این آموزش، با نحوه بدست آوردن اطلاعات Type ها آشنا شدیم و متد GetType و کلمه کلیدی typeof را بررسی کردیم. در این قسمت می خواهیم با نوشتن یک برنامه ساده با مکانیزم های مختلف بدست آوردن اطلاعات کلاس ها و همینطور اعضاء آن آشنا شویم. برای شروع کلاسی به صورت زیر تعریف می کنیم:

public class Person
{
    public Person(int id, string firstName, string lastName)
    {
        Id = id;
        FirstName = firstName;
        LastName = lastName;
    }

    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullName
    {
        get { return string.Format("{0} {1}", FirstName, LastName); }
    }

    public void DisplayFullName()
    {
        Console.WriteLine("{0} {1}", FirstName, LastName);
    }
}

کلاس تعریف شده یک سازنده دارد که سه پارامتر به عنوان ورودی دریافت می کند، سه خصوصیت با نام های Id و FirstName و LastName و همینطور یک خصوصیت با نام FullName که ReadOnly است بعلاوه یک متد با نام DisplayFullName که نام کامل شخص را در خروجی نمایش می دهد. می خواهیم بوسیله Reflection اطلاعات کاملی از این کلاس را در خروجی نمایش دهیم.

Console.WriteLine("Metadata Viewer:");
Console.WriteLine("-------------------------");
var type = typeof (Person);

Console.WriteLine("Namespace: {0}", type.Namespace);
Console.WriteLine("Assembly Name: {0}", type.Assembly.FullName);
Console.WriteLine("Data Type Name: {0}", type.Name);
Console.WriteLine("Reference/Value Type: {0}", type.IsValueType ? "Value Type" : "Reference Type");    

در مرحله بعدی اطلاعات مربوط به سازنده های کلاس را می خواهیم نمایش دهیم، کد زیر را در ادامه کد متد Main می نویسیم:

var constructors = type.GetConstructors();
Console.WriteLine();
Console.WriteLine("Constructors:");
Console.WriteLine("------------------------");
foreach (ConstructorInfo constructorInfo in constructors)
{
    List parameters = new List();
    foreach (ParameterInfo parameterInfo in constructorInfo.GetParameters())
    {
        parameters.Add(string.Format("{0} {1}", parameterInfo.ParameterType.Name, parameterInfo.Name));
    }
    Console.Write("{0}({1})", type.Name, string.Join(",", parameters));
    Console.WriteLine();
}

در کد بالا ابتدا لیست سازنده های Type را با دستور GetConstructors بدست آوردیم. نوع بازگشتی این متد آرایه ای از ConstructorInfo می باشد که اطلاعات مربوط به هر سازنده را در خود نگه می دارد. در ادامه با دستور foreach لیست سازنده ها را پیمایش کرده و آن ها را در خروجی نمایش می دهیم. دقت کنید در داخل حلقه foreach لیست پارامترهای مربوط به سازنده را توسط دستور GetParameters بدست آوردیم که آرایه ای از نوع ParameterInfo بر میگرداند. این کلاس اطلاعات مربوط به پارامتر را به ما می دهد. داخل لیستی از رشته ها، اطلاعات مربوط به پارامتر را که شامل نوع داده پارامتر و نام آن است ذخیره می کنیم. برای بدست آوردن نوع داده پارامتر کافیست از خصوصیت ParameterType که در کلاس ParameterInfo تعریف شده استفاده کنیم. در انتها نام سازنده به همراه پارامترهای آن را در خروجی در قالب زیر چاپ می شود:

Person(Int32 id,String firstName,String lastName)

در قدم بعدی می خواهیم لیست متدهای کلاس را پیدا کنیم. برای اینکار کد زیر را در ادامه کد قبل اضافه کنید:

var methods = type.GetMethods();
Console.WriteLine();
Console.WriteLine("Methods:");
Console.WriteLine("------------------------");
foreach (MethodInfo methodInfo in methods)
{
    List parameters = new List();
    foreach (ParameterInfo parameterInfo in methodInfo.GetParameters())
    {
        parameters.Add(string.Format("{0} {1}", parameterInfo.ParameterType.Name, parameterInfo.Name));
    }
    Console.Write("{0} {1}({2})",methodInfo.ReturnType.Name, methodInfo.Name, string.Join(",", parameters));
    Console.WriteLine();
}

دستور GetMethods آرایه ای از نوع MethodInfo بر می گرداند که این کلاس شامل اطلاعات مربوط به متد تعریف شده می باشد. با اجرای کد بالا، خروجی زیر نمایش داده می شود:

Methods:
------------------------
Int32 get_Id()
Void set_Id(Int32 value)
String get_FirstName()
Void set_FirstName(String value)
String get_LastName()
Void set_LastName(String value)
String get_FullName()
Void DisplayFullName()
String ToString()
Boolean Equals(Object obj)
Int32 GetHashCode()
Type GetType()

لیستی از متدها برای ما نمایش داده شدند، اما دقت کنید، متدهای با نام getId و setId یا getFirstName و setFirstName هم در لیست وجود دارند. دلیل این موضوع نحوه رفتار کامپایلر با خصوصیات است. زمان کامپایل خصوصیات تعریف شده به متدهایی تبدیل می شوند که برای قسمت های get و set می باشند. برای عدم نمایش این متدها در لیست کد بالا را به صورت زیر تغییر می دهیم:

var methods = type.GetMethods();
Console.WriteLine();
Console.WriteLine("Methods:");
Console.WriteLine("------------------------");
foreach (MethodInfo methodInfo in methods)
{
    if(methodInfo.IsSpecialName)
        continue;
    List parameters = new List();
    foreach (ParameterInfo parameterInfo in methodInfo.GetParameters())
    {
        parameters.Add(string.Format("{0} {1}", parameterInfo.ParameterType.Name, parameterInfo.Name));
    }
    Console.Write("{0} {1}({2})",methodInfo.ReturnType.Name, methodInfo.Name, string.Join(",", parameters));
    Console.WriteLine();
}

دقت کنید، کد زیر به بدنه foreach اضافه شده است:

if(methodInfo.IsSpecialName)
    continue;

در صورتی که متد توسط خود کامپایلر به کلاس اضافه شده باشد، خصوصیت IsSpecialName مقدار true بر میگرداند. بعد از اعمال تغییرات تنها متدهایی که در کلاس Person و کلاس های پدر تعریف شده باشند نمایش داده می شود. متد هایی مانند ToString یا GetHashCode در کلاس Object تعریف شده اند.

در ادامه می خواهیم لیستی از خصوصیات کلاس را در خروجی نمایش دهیم. برای اینکار کد زیر را در ادامه می نویسیم:

var properties = type.GetProperties();
Console.WriteLine();
Console.WriteLine("Properties:");
Console.WriteLine("------------------------");
foreach (PropertyInfo propertyInfo in properties)
{
    if (propertyInfo.GetMethod != null && propertyInfo.SetMethod != null)
    {
        Console.WriteLine("{0} {{ get; set; }}", propertyInfo.Name);
    }
    else if (propertyInfo.GetMethod != null && propertyInfo.SetMethod == null)
    {
        Console.WriteLine("{0} {{ get; }}", propertyInfo.Name);
    }
    else
    {
        Console.WriteLine("{0} {{ set; }}", propertyInfo.Name);
    }
}

بوسیله متد GetProperties لیستی از خصوصیات داخل کلاس را بدست آوردیم. خروجی این متد آرایه ای از نوع PropertyInfo می باشد. این کلاس اطلاعات مربوط به خصوصیت تعریف شده در کلاس را به ما می دهد. در ادامه بوسیله دستور foreach لیست خصوصیات را پیمایش می کنیم. در داخل بدنه foreach، همانطور که مشاهده می کنید، با دستور if بررسی می کنیم که خصوصیات مورد نظر بدنه های get و set را شامل می شود یا خیر. خصوصیت SetMethod اطلاعات مربوط به بخش set و خصوصیت GetMethod اطلاعات مربوط به بخش get را برای ما بر میگرداند. در صورتی عدم وجود هر یک از این بخش ها، خصوصیت مورد نظر مقدار null را بر میگرداند. برای مثال، برای خصوصیت FullName، به دلیل اینکه بخش set نوشته نشده، SetMethod مقدار null را بر خواهد گرداند. خروجی کد بالا به صورت زیر خواهد بود:

Properties:
------------------------
Id { get; set; }
FirstName { get; set; }
LastName { get; set; }
FullName { get; }

در این قسمت از آموزش، با نحوه دریافت برخی از اطلاعات کلاس ها آشنا شدیم و کلاس های زیر را بررسی کردیم:

  1. کلاس Type: شامل اطلاعات مربوط به یک نوع داده که می تواند یک class یا struct یا delegate و نوع های داده پیش فرض دات نت باشد.
  2. متد GetConstrcutors: دریافت لیست سازنده های تعریف شده در یک Type
  3. کلاس ConstructorInfo: شامل اطلاعات مربوط به یک سازنده
  4. متد GetParameters: دریافت لیست پارامترهای تعریف شده در یک سازنده یا یک متد
  5. کلاس ParameterInfo: شامل اطلاعات مربوط به یک پارامتر
  6. متد GetMethods: دریافت لیست متدهای یک Type
  7. کلاس MethodInfo: شامل اطلاعات مربوط به یک متد
  8. متد GetProperties: دریافت لیست متدهای تعریف شده در یک Type
  9. کلاس PropertyInfo: شامل اطلاعات مربوط به یک Property
  10. خصوصیات GetMethod و SetMethod: این خصوصیات در کلاس PropertyInfo تعریف شده و اطلاعات مربوط به بخش های get و set یک property را به ما می دهد

کلاس های دیگری نیز در فضای نام System.Reflection وجود دارند مانند:

  1. EventInfo: اطلاعات مربوط به یک Event
  2. FieldInfo: اطلاعات مربوط به یک Field
  3. MemberInfo: کلاس پایه ای که کلیه کلاس های ParameterInfo، FieldInfo، ConstructorInfo و MethodInfo از آن مشتق شده اند

همچنین متدهای دیگری برای کلاس Type وجود دارند:

  1. متد GetEvents: دریافت لیست Event های تعریف شده در یک Type
  2. متد GetFields: دریافت لیست Field های تعریف شده در یک Type
  3. متد GetInterfaces: دریافت لیست Interface هایی که Type مورد نظر پیاده سازی کرده است

و متدهای دیگر که می توانید از بخش Documentation مایکروسافت به توضیحات آن ها دسترسی داشته باشید.

امیدوارم که این آموزش برای شما عزیزان مفید واقع شود. در قسمت بعدی در مورد Late-Binding و نحوه ساخت اشیاء، فراخوانی متدها و مقدار دهی خصوصیات توسط Reflection صحبت خواهیم کرد. ITPRO باشید

نویسنده: حسین احمدی
انجمن تخصصی فناوری اطلاعات ایران
#آموزش_reflection_در_سی_شارپ #آموزش_زبان_سی_شارپ #استخراج_metadata_توسط_reflection #کاربرد_reflection_در_سی_شارپ
عنوان
1 آموزش Reflection در برنامه های دات نت قسمت 1 : معرفی رایگان
2 آموزش Reflection در برنامه های دات نت قسمت 2 : Meta Data Viewer رایگان
3 آموزش Reflection در برنامه های دات نت قسمت 3 : Late Binding رایگان
4 آموزش Reflection در برنامه های دات نت قسمت 4 : Attibute ها رایگان
زمان و قیمت کل 0″ 0
0 نظر

هیچ نظری ارسال نشده است! اولین نظر برای این مطلب را شما ارسال کنید...

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره تابستانه می تونی امروز ارزونتر از فردا خرید کنی ....