كيفية القيام بما يلي: تعريف,بدء تشغيل, واستخدام التفويض (إرشادات برمجة C#)
في C# "1. 0" والإصدارات الأحدث، يمكنك تعريف التفويضات كما هو موضح هنا:
public delegate void Del<T>(T item);
public void Notify(int i) { }
Del<int> d1 = new Del<int>(Notify);
في C# "2. 0" والإصدارات الأحدث، من الممكن أيضاً استخدام الطرق المجهولة لتعريف وإعادة تهيّيئ التفويض باستخدام تبسيط بناء الجملة:
Del<int> d2 = Notify;
في C# 3.0 والإصدارات الأحدث، يمكن للتفويضات أيضاً تعريف وإعادة إنشاء مثيل باستخدام تعبير لامدا. لمزيد من المعلومات، راجع تعبيرات لامدا (ارشادات برمجة C#).
يوضح المثال التالي تعريف إنشاء واستخدام التفويض. فئة الـ BookDBتقوم بتغليف قاعدة بيانات المكتبة التي تحتفظ بها قاعدة بيانات الكتب. إنها تعبر عن أسلوب ProcessPaperbackBooks، الذي يبحث عن كل كتب ورقية الغلاف في قاعدة بيانات ويستدعي تفويضاً لكل منها. النوع delegate المستخدم يكون مسمى بـ ProcessBookDelegate. الفئة Test تستخدم هذه الفئة لطباعة العناوين والرموز متوسط السعر للكتب ورقية الغلاف.
استخدام التفويضات يعزز الفصل الجيد بين وظائف من قاعدة بيانات المكتبة والتعليمات البرمجية للعميل. التعليمات البرمجية للعميل لا تحتوي معلومات عن كيفية تخزين الكتب أو كيف للتعليمات البرمجيةالخاصة بالمكتبة العثور على الكتب ورقية الغلاف. تعليمات المكتبة البرمجية ليس لديها معرفة للعمليات التي يتم تنفيذها على الكتب ورقية الغلاف بعد عثوره عليها.
مثال
// A set of classes for handling a bookstore:
namespace Bookstore
{
using System.Collections;
// Describes a book in the book list:
public struct Book
{
public string Title; // Title of the book.
public string Author; // Author of the book.
public decimal Price; // Price of the book.
public bool Paperback; // Is it paperback?
public Book(string title, string author, decimal price, bool paperBack)
{
Title = title;
Author = author;
Price = price;
Paperback = paperBack;
}
}
// Declare a delegate type for processing a book:
public delegate void ProcessBookDelegate(Book book);
// Maintains a book database.
public class BookDB
{
// List of all books in the database:
ArrayList list = new ArrayList();
// Add a book to the database:
public void AddBook(string title, string author, decimal price, bool paperBack)
{
list.Add(new Book(title, author, price, paperBack));
}
// Call a passed-in delegate on each paperback book to process it:
public void ProcessPaperbackBooks(ProcessBookDelegate processBook)
{
foreach (Book b in list)
{
if (b.Paperback)
// Calling the delegate:
processBook(b);
}
}
}
}
// Using the Bookstore classes:
namespace BookTestClient
{
using Bookstore;
// Class to total and average prices of books:
class PriceTotaller
{
int countBooks = 0;
decimal priceBooks = 0.0m;
internal void AddBookToTotal(Book book)
{
countBooks += 1;
priceBooks += book.Price;
}
internal decimal AveragePrice()
{
return priceBooks / countBooks;
}
}
// Class to test the book database:
class TestBookDB
{
// Print the title of the book.
static void PrintTitle(Book b)
{
System.Console.WriteLine(" {0}", b.Title);
}
// Execution starts here.
static void Main()
{
BookDB bookDB = new BookDB();
// Initialize the database with some books:
AddBooks(bookDB);
// Print all the titles of paperbacks:
System.Console.WriteLine("Paperback Book Titles:");
// Create a new delegate object associated with the static
// method Test.PrintTitle:
bookDB.ProcessPaperbackBooks(PrintTitle);
// Get the average price of a paperback by using
// a PriceTotaller object:
PriceTotaller totaller = new PriceTotaller();
// Create a new delegate object associated with the nonstatic
// method AddBookToTotal on the object totaller:
bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);
System.Console.WriteLine("Average Paperback Book Price: ${0:#.##}",
totaller.AveragePrice());
}
// Initialize the book database with some test books:
static void AddBooks(BookDB bookDB)
{
bookDB.AddBook("The C Programming Language", "Brian W. Kernighan and Dennis M. Ritchie", 19.95m, true);
bookDB.AddBook("The Unicode Standard 2.0", "The Unicode Consortium", 39.95m, true);
bookDB.AddBook("The MS-DOS Encyclopedia", "Ray Duncan", 129.95m, false);
bookDB.AddBook("Dogbert's Clues for the Clueless", "Scott Adams", 12.00m, true);
}
}
}
/* Output:
Paperback Book Titles:
The C Programming Language
The Unicode Standard 2.0
Dogbert's Clues for the Clueless
Average Paperback Book Price: $23.97
*/
برمجة نشطة
تعريف التفويض.
يقوم الكشف التالي بتعريف نوع تفويض جديد.
public delegate void ProcessBookDelegate(Book book);
كل نوع تفويض يصف العدد و أنواع الوسائط و نوع القيمة الإرجاع من الأساليب التي يمكن تغليفها. كلما لزم مجموعة جديدة من أنواع وسيطة أو نوع القيمة الإرجاع، فإن يجب تعريف نوع تفويض جديد.
إنشاء تفويض.
بعد أن تم التصريح عن نوع التفويض يجب إنشاء كائن مفوض كما المقترن مع أسلوب معين. في المثال السابق، يمكنك القيام بذلك عن طريق تمرير الأسلوب PrintTitle إلى الأسلوب ProcessPaperbackBooks كما هو موضح في المثال التالي:
bookDB.ProcessPaperbackBooks(PrintTitle);
يؤدي هذا إلى إنشاء كائن مفوض جديد مقترن مع ثابت أسلوب Test.PrintTitle. وبشكل مماثل، الأسلوب الغير الثابت AddBookToTotal في الكائن totaller يتم تمريره كما هو موضح في المثال التالي:
bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);
في كل الحالات يتم تمرير كائن مفوض جديد لأسلوب ProcessPaperbackBooks.
بعد إنشاء التفويض فإن الأسلوب الذي يرتبط به لا يتغير أبداً؛ كائنات المفوض غير قابلة للتغيير.
استدعاء التفويض.
بعد إنشاء كائن مفوض، عادة ما يتم تمرير المفوض لتعليمات برمجية أخرى والتي ستقوم باستدعاء المفوض. يتم استدعاء كائن التفويض باستخدام اسم كائن التفويض متبوعاً بالوسيطات الموجودة بين قوسين لتمريرها إلى التفويض. المثال التالي هو لاستدعاء التفويض:
processBook(b);
يمكن للمفوض إما القيام باستدعاء متزامن, كما هو موضح في هذا المثال أو بشكل غير متزامن باستخدام أساليب BeginInvoke و EndInvoke .
راجع أيضًا:
المرجع
التفويضات (دليل البرمجة لـ #C)