در کلاس CCommObj که با آن آشنا شدیم ، آرایه ای Private از نوع ICommObjEvents به نام m_arSinkColl وجود دارد. این آرایه تمام اینترفیس های sink شده را ذخیره می کند. واژه ی sink در اینجا به کلاسی گفته می شود که دریافت کننده ی رخدادها است. متد Advise تنها sink وارده به آنرا در یک آرایه ذخیره می کند و سپس اندیس آرایه را که در اینجا cookie نامیده شده است بر می گرداند. این کوکی توسط کلاینتی که دیگر نمی خواهد از آن آیتم هیچونه رخدادی را دریافت کند به سرور فرستاده می شود و سپس سرور این آیتم را از لیست خودش حذف خواهد کرد.
نحوه ی فراخوانی متد advise توسط کلاینت نیز جالب است.
کد:
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
string strAdd = ("Hello");
m_Server.read (strAdd,10);
}
در اینجا تنها یک this بعنوان آرگومان به متد advice فرستاده شده است در حالیکه انتظار می رفت آرگومانی از نوع ICommObjEvents به تابع فرستاده شود. دلیل صحت این عمل بدین صورت است که کلاس ClientApp_A از اینترفیس ICommObjEvents ارث برده است و آنرا پیاده سازی نموده است.
در ادامه لیست کامل برنامه ی نوشته شده را در حالت Console ملاحظه می فرمایید.
کد:
namespace CSharpCenter
{
using System;
public interface ICommObjEvents
{
void OnDataSent();
void OnError();
}
public class CCommObj
{
private int m_nIndex;
public ICommObjEvents [] m_arSinkColl;
public CCommObj()
{
m_arSinkColl = new ICommObjEvents[10];
m_nIndex = 0;
}
public void Advise(ICommObjEvents theSink)
{
m_arSinkColl[m_nIndex] = theSink;
m_nIndex++;
}
public void SendData(string strData)
{
foreach ( ICommObjEvents theSink in m_arSinkColl)
{
if(theSink != null )
{
theSink.OnDataSent ();
}
}
}
}
class CClientApp_A:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent Client App A");
}
public void OnError()
{
Console.WriteLine("OnError");
}
public void Read()
{
string strAdd = ("Hello");
m_Server.SendData (strAdd);
}
private CCommObj m_Server;
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
}
}
class CClientApp_B:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent Client App B");
}
public void OnError()
{
Console.WriteLine("OnError");
}
private CCommObj m_Server;
public void Init(CCommObj theSource)
{
m_Server = theSource;
theSource.Advise (this);
}
}
class ConsoleApp
{
public static void Main()
{
CClientApp_A theClient = new CClientApp_A ();
CClientApp_B theClient2 = new CClientApp_B ();
CCommObj theComm = new CCommObj ();
theClient.Init (theComm);
theClient2.Init (theComm);
theClient.Read();
}
}
}
در متد Main برنامه ی فوق ، ما دو کلاینت تعریف کرده ایم و یک نمونه از CCommObj را. دو کلاینت instance های CCommObj را بعنوان آرگومان دریافت کرده اند. در هنگام فراخوانی init توسط هر کلاینت متد advise فراخوانی می گردد. در خاتمه Read مربوط به کلاینت 1 فراخوانی شده است که سبب می شود تا رخداد OnDataSend شیء CCommObj اجرا شود و به تمام کلاینت ها فرستاده شود.
هدف از این مثال ارائه ی بعضی از جنبه های اینترفیس ها و نحوه ی استفاده از آنها بود. دو مطلب دیگر در مورد اینترفیس ها باقی مانده اند تا به پایان بحث مربوط به آنها برسیم:
چگونه می توان متوجه شد که یک شیء واقعا یک اینترفیس را پیاده سازی کرده است؟
دو روش برای فهمیدن این موضوع وجود دارد:
- استفاده از کلمه ی کلیدی is
- استفاده از کلمه ی کلیدی as
اولین مثال زیر از کلمه ی کلیدی is استفاده می کند :
کد:
CClientApp_C theClient3 = new CClientApp_C ();
if(theClient3 is ICommObjEvents)
Console.WriteLine ("theClient3 implements ICommObjEvents");
else
Console.WriteLine ("theClient3 doesnot implement ICommObjEvents");
کلمه ی کلیدی is مقدار true را بر می گرداند اگر اپراتور سمت چپ ، اینترفیس سمت راست را پیاده سازی کرده باشد.
کد:
ICommObjEvents theClient5 = theClient3 as ICommObjEvents;
if(theClient5 != null )
Console.WriteLine ("Yes theClient implements interface");
else
Console.WriteLine ("NO,Yes theClient doesn't implements interface");
در مثال فوق اپراتور as در حال casting شیء theClient5 به ICommObjEvents می باشد. چون CClientApp_C اینترفیس را پیاده سازی نمی کند حاصل خط اول نال خواهد بود.
به صورت خلاصه :
یک اینترفیس قراردادی است که به کلاینت گارانتی می دهد یک کلاس خاص چگونه رفتار خواهد کرد. هنگامیکه کلاسی یک اینترفیس را پیاده سازی می کند به تمام کلاینت ها می گوید که : من تمام موارد ذکر شده در اینترفیس را ارائه و پیاده سازی خواهم کرد. نمونه ی عملی استفاده از اینترفیس ها بحث dot net remoting است.