درس شانزدهم (قسمت اول) - استفاده از صفتها در C#

 
ارسال شده در تاریخ 1394/5/22 توسط admin در زمینه آموزش سی شارپ
 
آموزش زبانهای برنامه نویسی کامپیوتری

در این درس با نحوه استفاده از صفتها در زبان C# آشنا خواهید شد . اهداف ما در این درس به شرح زیر است :
1- صفتها چه هستند و چرا از آنها استفاده میکنیم
2- استفاده از صفتهای تک پارامتری و چند پارامتری
3- انواع پارامترهای صفت پارامترهای Named
Positional Target -4 های صفتها عناصری که صفتها بر روی آنها اعمال می شوند
5- تولید صفتهای شخصی
6- تعریف و یا کنترل موارد استفاده از یک صفت
7- استفاده از پارامترهای Positional و Named در صفتهای شخصی
8- انواع (type) معتبر برای پارامترهای صفت
9- استفاده از صفتها در زمان اجرا
10- خلاصه مطالب
11- منابع

 صفتها در حقیقت اطلاعات توضیحی هستند که می توانید آنها را به برنام ه های خود بیفزایید صفتها را می توان برای کلیه عناصر برنامه از قبیل کلاسها، واسطها، اسمبلی ها و ... مورد استفاده قرار داد .از این اطلاعات می توان برای موارد متنوعی در زمان اجرای برنامه استفاده ن مود برای مثال می توان به صفتی مانند DllImportAttribute اشاره کرد که امکان برقراری ارتباط با توابع کتابخانه ای Win32 را فراهم می نماید همچنین صفتهایی نیز وجود دارند که برنام هنویس یا توسعه دهنده برنامه را در امر تولید برنامه یاری می نمایند برای مثال می توان به صفت ObsoleteAttribute اشاره کرد که با استفاده از آن، در زمان کامپایل برنامه پیغامی برای برنامه نویس نمایش داده می شود و مشخص می کند که متدی خاص مورد استفاده قرار نگرفته و یا دیگر مورد استفاده نیست همچنین هنگامیکه با فرمهای ویندوز کار می کنیم، صفتها ی بسیاری وجود دارند که امکان استفاده از این فرمها را فراهم کرده و باعث می شوند تا اطلاعات مربوط به این عناصر در property فرم ظاهر شوند یکی دیگر از موارد استفاده از صفتها در مسایل امنیتی اسمبلی های .Net است برای مثال صفتهایی وجود دارند که باعث جلوگیری از فراخوانی های غیر مجاز می شوند، بدین معنی که تنها اجازه فراخوانی را به متدها یا اشیایی می دهند که قبلا تعریف شده و مشخص شده باشند .

 
یکی از علتهای استفاده از صفتها آنست که، اغلب سرویسهایی را که آنها برای کاربر فراهم می نمایند، بسیار پیچیده است و با کدهای معمولی نمی توان آنرا را بدست آورد از اینرو استفاده از صفتها در بسیاری از موارد ضروری و اجتناب ناپذیر است همانطور که خواهید دید، صفتها به برنام ه های ما Metadata اضافه مینمایند پس از کامپایل برنامه های C# ، فایل اسمبلی برای آن ایجاد می گردد که این اسمبلی معمولا یا یک فایل اجرایی است و یا یک Dll است توصیف اسمبلی، در Metadata ی مربوط به
آن قرار می گیرد طی پروسه ای تحت عنوان Reflection ، صفت یک برنامه از طریق فایل Metadata ی موجود در اسمبلی آن قابل دسترس می گردد ). . برای آشنایی بیشتر با اسمبلی و Metadataمیتوانید به کامپایل یک برنامه سی شارپ در همین سایت مراجعه نمایید (. در حقیقت صفتها، کلاسهایی هستند که می توانید آنها را با زبان C# تولید کرده و جهت افزودن اطلاعاتی توضیحی به کد خود، از آنها استفاده نمای ید این اطلاعات در زمان اجرای برنامه از طریق Reflection قابل دسترسی هستند .
 
 
در این درس با روش استفاده از صفتها و چگونگی ارتباط دادن آنها با عناصر مختلف برنامه آشنا خواهید شد .
 
مفاهیم اولیه درباره صفتها
 
صفتها را معمولا قبل از اعلان عنصر مورد نظر در برنامه قرار می دهند اعلان صفتها بدین صورت است که نام صفت درون دو براکت قرار میگیرد .
[ObsoleteAttribute]
استفاده از کلمه Attribute در اعلان صفت الزامی نیست، از اینرو اعلان زیر با اعلان فوق یکسان است :
[Obsolete]
همچنین صفتها می توانند دارای پارامتر نیز باشند که با استفاده از آنها خواص بیشتری را در اختیار برنام ه قرار می دهند در مثال 16-1 موارد متنوعی از استفاده صفت ObsoleteAttribute را مشاهده می نمایید .
 
مثال : 16-1 نحوه استفاده از صفتها
 
using System;
 
class BasicAttributeDemo
{
[Obsolete]
public void MyFirstDeprecatedMethod()
{
Console.WriteLine("Called MyFirstDeprecatedMethod().");
}
 
[ObsoleteAttribute]
public void MySecondDeprecatedMethod()
{
Console.WriteLine("Called MySecondDeprecatedMethod().");
}
 
[Obsolete("You shouldn"t use this method anymore.")] public void MyThirdDeprecatedMethod()
{
Console.WriteLine("Called MyThirdDeprecatedMethod().");
}
 
// make the program thread safe for COM [STAThread]
static void Main(string[] args)
{
BasicAttributeDemo attrDemo = new BasicAttributeDemo();
 
attrDemo.MyFirstDeprecatedMethod(); attrDemo.MySecondDeprecatedMethod(); attrDemo.MyThirdDeprecatedMethod();
}
}
 
 
همانطور که در مثال 16-1 نیز مشاهده می شود، صفت Obsolete در فرمهای مختلف مورد استفاده قرار گرفته است اولین محلی که از این صفت استفاده شده است، متد MyFirstDeprecatedMethod() و پس از آن در متد
MySecondDeprecatedMethod() است تنها تفاوت استفاده در این دو حالت آنست که در متد دوم صفت با نام کامل یعنی به همراه کلمه Attribute مورد استفاده قرار گرفته است نتیجه هر دو اعلان یکسان است همانطور که گفته بودیم، صفتها میتوانند دارای پارامتر نیز باشند :
 
[Obsolete("You shouldn"t use this method anymore.")] public void MyThirdDeprecatedMethod() ...
این پارامتر، ویژگی خاصی را به صفت می افزاید که آ ن را با دو اعلان قبلی متمایز می نماید نتیجه هر سه اعلان این صفت در زیر آورده شده است این پیغامها، پیامهای کامپایلر C# هستند که به هنگام کامپایل برنامه تولید شد هاند .
 
 
>csc BasicAttributeDemo.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.2292.4 for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.
 
BasicAttributeDemo.cs(29,3): warning CS0612:
"BasicAttributeDemo.MyFirstDeprecatedMethod()" is obsolete BasicAttributeDemo.cs(30,3): warning CS0612:
"BasicAttributeDemo.MySecondDeprecatedMethod()" is obsolete BasicAttributeDemo.cs(31,3): warning CS0618:
"BasicAttributeDemo.MyThirdDeprecatedMethod()" is obsolete: "You shouldn"t use this method anymore."
 
همانطور که ملاحظه می کنید، سومین اعلا ن صفت در این برنامه که با پارامتر همراه بود، باعث شده است تا پارامتر صفت نیز به عنوان بخشی از پیام نمایش داده شده توسط کامپایلر، نشان داده شود در مورد دو صفت دیگر نیز مشاهد ه میشود که تنها پیغامی ساده تولید گردیده است .
 
مثال 16-1 شامل صفت دیگری نیز می باشد این صفت STAThreadAttribute است که معمولا در ابتدای کلیه برنامه های
C# و قبل از آغاز متد Main() قرار می گیرد این صفت بیان می دارد که برنامه C# مورد نظر می تواند با کد مدیریت نشده COM از طریق Simple Threading Apartment ارتباط برقرار نماید استفاده از این صفت در هر برنامه ای می تواند مفید باشد، چراکه شما بعنوان برنامه نویس هیچ گاه اطلاع ندارید که آیا کنابخانه ثالثی که از آن استفاده میکنید، قصد برقراری ارتباط با
COM را دارد یا نه؟ در صورتیکه با برخی از اصطلاحات بکار رفته آشنایی ندارید اصلا نگران نشوی د در اینجا هدف تنها نشان دادن موارد استفاده از صفتهاست (.
 
صفتها میتوانند دارای چندین پارامتر باشند در مثال 16-2 ، استفاده از دو پارامتر برای یک صفت نشان داده شده است .
 
مثال 16-2
 
using System;
public class AnyClass
{
[Obsolete("Don"t use Old method, use New method", true)]
 
static void Old( ) { }
 
static void New( ) { }
 
public static void Main( )
{
Old( );
}
}
همانطور که در مثال 16-2 مشاهده می کنید، صفت مورد استفاده دارای دو پارامتر است پارامتر اول که یک جمله متنی است و همانند مثال 16-1 عمل می کند پارامتر دوم نیز بیان کننده نوع پیغامی است که این صفت در هنگام کامپایل تولید می کند در صورتیکه این مقدار برابر با True باشد، بدین معناست که در هنگام کامپایل پیغام خطا تولید میشود و کامپایل برنامه متوقف می گردد در حالت پیش فرض مقدار این پارامتر برابر با False است که بیان می دارد، به هنگام کامپایل تنها پیغام هشداری تولید خواهد شد در پیغام این برنامه، عنصری از برنامه را که نباید از آن استفاده شود معین شده و جایگزین آن نیز معرفی میشود .
 
 
AnyClass.Old()" is obsolete: "Don"t use Old method, use New method"
 
نکته مهمی که باید در مورد صفتها در نظر بگیرید آنست که اطلاعاتی که توسط صفت در کد برنامه قرار می گیرد، توسط سایر برنامه ها نیز قابل تفسیر و استفاده است .
 
انواع پارامترهای صفت پارامترهای Positional و (Named
همانطور که در بالا نیز اشاره شد، صفتها می توانند دارای پارامتر نیز باشند این پارامترها به دو دسته تقسیم میشوند پارامترهای محلی (positional) و پارامترهای اسمی .(named) از پارامترهایpositional در زمانی استفاده می شود که می خواهیم پارامتر مورد نظر بصورت اجباری مورد استفاده قرار گیرد و البته این مسئله یک قانون نیست چراکه در مورد صفت Obsolete ، این صفت دارای یک پارامتر positional دیگر با نام error و از نوع int نیز می باشد که ما آنرا در مث ال 16-1 لحاظ نکردی م همانطور که در مثال 16-2 مشاهده کردید، از این پارامتر positional می توان برای ایجاد یک خطا در زمان کامپایل برنامه استفاده نمود .
 
[Obsolete("Don"t use Old method, use New method", true)] static void Old( ) { }
 
تفاوت پارامترهای positional با پارامترهای named در آنست که، پارامترهای named با نامشان مورد استفاده قرار می گیرند و همیشه اختیاری هستند در مثال 16-3 صفت DllImport را مشاهده می نمایید که دارای هر دو نوع پارامتر positional و named است .
 
مثال 16-3
 
 
using System;
using System.Runtime.InteropServices;
 
class AttributeParamsDemo
{
 
[DllImport("User32.dll", EntryPoint="MessageBox")] static extern
int MessageDialog(int hWnd, string msg, string caption, int msgType);
 
[STAThread]
static void Main(string[] args)
{
MessageDialog(0, "MessageDialog Called!", "DllImport Demo", 0);
}
}
صفت DllImport در مثال 16-3 دارای یک پارامتر ("User32.dll") positional و یک پارامتر named
(EntryPoint="MessageBox") است پارامترهای named در هر مکانی می توانند قرار گیرند و مانند پ ارامترهای positional دارای محدودیت مکانی نیستند بدین معنا که چون در پارامترهای named ، نام پارامتر مستقیما مورد استفاده
قرار می گیرد، محل قرار گیری آن در لیست پارامترهای صفت مهم نیست اما در مورد پارامترهای positional چون اسم پارامتر مورد استفاده قرار نمی گیرد، این پارامترها حتما باید در مکانهای تعیین شده و تعریف شده در لیست پارامترهای صفت قرار گیرن د توجه کنید که چون هدف ما تنها آشنایی با صفتها و نحوه استفاده از آنهاست، درباره پارامترهای مختلف صفت DllImport بحث نخواهیم کرد چراکه پارامترهای این صفت نیاز به آشنایی کامل با Win32 API دارد .
 
در یک بررسی کلی میتوان گفت که پارامترهای Positional ، پارامترهای سازنده (Constructor) صفت هستند و در هر بار استفاده از صفت باید مورد استفاده قرار گیرند، ولی پارامترهای Named کاملا اختیاری هستند و همیشه نیازی به استفاده از آنها نمی باشد .
 
Target های صفتها عناصری که صفتها بر روی آنها اعمال می شوند (
صفتهایی که تا کنون مشاهده کردید، همگی بر روی متدها اعمال شده بودن د اما عناصر مختلف دیگری در C# وجود دارند که می توان صفتها را بر روی آنها اعمال نمود جدول 16-1 عناصر مختلف زبان C#را که صفتها بر روی آنها اعمال میشوند را نشان میدهد .
 
قابل اعمال به .... عناصر اعمال شونده به تمامی عناصر قابل اعمال هستند all . به تمام یک اسمبلی assembly کلاسها class
سازند ه ها constructor Delegate ها delegates عناصر شمارشی enum رخدادها event فیلدها field واسطها interface
 
متدها method
ماژولها کدهای کامپایل شده ای که می توانند به عنوان قسمتی از یک اسمبلی در نظر گرفته شوند (.
module
پارامترها parameter Property ها property مقادیر بازگشتی returnvalue ساختارها struc
 
هر چند ممکن است استفاد ه از این Target ها باعث ایجاد ابهام شوند، اما می توان با استفاده از این Target ها معین کرد که صفت دقیقا به عنصر مورد نظر اعمال شود یکی از صفتهایی که بر روی اسمبلی اعمال می شود و باعث ارتباط با CLS می گردد، صفت CLSCompliantAttribute است CLS . یا همان Common Language Specification امکان برقراری ارتباط بین کلیه زبانهایی که تحت .Net کار می کنند را فراهم مینماید Target . های صفتها با استفاده از اسم Target که بعد از آن کولون قرار میگیرد، ا یجاد میشوند در مثال 16-4 نحوه استفاده از این صفت نشان داده شده است .
 
مثال 16-4
 
using System;
 
[assembly:CLSCompliant(true)]
 
public class AttributeTargetDemo
{
public void NonClsCompliantMethod(uint nclsParam)
{
Console.WriteLine("Called NonClsCompliantMethod().");
}
 
[STAThread]
static void Main(string[] args)
{
uint myUint = 0;
 
AttributeTargetDemo tgtDemo = new AttributeTargetDemo();
 
tgtDemo.NonClsCompliantMethod(myUint);
}
}
Copyright © 2014 icbc.ir