ProgramatorCZ  |   Diskusní fórum  |   ASMDprojekt  |   Vtipy  |   JavaScript
Spolupracujeme:   WebGuru  |   Komplikátor  |   MinaSite Přidat k oblíbeným položkám  |   Nastavit jako výchozí stránku
Časopis
Hlavní stránka
Assembler
C,C++
Delphi
DOTNET
Flash
HTML
Java
JavaScript
Knihy
O Internetu
Pascal
PHP
Pro. programátor
Programy
Python
Tiskové zprávy

Projekty

JScript Planet
ProProjekty

Služby

Monitoring

Informace
Redakce
O časopisu
Odkazy
Nový redaktor


ISSN 1213-7359

Šéfredaktor:
Jan Sova

Zástupci šéfredaktora
Frerenzy Dawid
Krásenský David

Šéfredaktoři rubrik
Michal Chalupník
Formánek Jiří
Pavel Aleš
Sojka Zdeněk
Petr Rympler

Administrátor
Jan Sova

Naše ikonka
MinaSite
Komplikátorovy Stránky
TOPlist
GALACTICA

Časopis používá redakční systém Sova-Press.



Práce v .NET Framework - Zástupci v rubrice DOTNET

Vážení čtenáři. Chtěli bychom vám předložit několik příspěvků zaměřených na programování v Microsoft .NET Framework. Jejich úkolem bude ukázat na důležité a zajímavé rysy tohoto prostředí. Zatím máme v úmyslu věnovat se zástupcům, událostem a potom vláknům. K výkladu budeme používat programovací jazyk C#. V tomto příspěvku se zaměříme na práci se zástupci (angl. delegate) v .NET Framework.

Zástupci v .NET

         Zástupce je typově bezpečná reference (ukazatel) na metodu. K vytvoření zástupce musíme nejdříve mít potřebné informace o metodě (funkci) na kterou bude náš zástupce ukazovat. Jsou to: návratový typ metody, seznam parametrů, jejich datové typy a modifikátory (ref, out).  Na základě těchto údajů deklarujeme nejprve zástupce jako datový typ. K tomu používáme klíčové slovo delegate.

        Chceme-li např. deklarovat zástupce na funkce, které jsou typu float, s jedním parametrem typu float, napíšeme

public delegate float MyDelegate(float x);

        Takto jsme vytvořili nový datový typ zástupce nazvaný MyDelegate. Překladač generuje z tohoto typu třídu, z níž děláme konkrétní objekty, ukazatele na konkrétní funkce vyhovující typu zástupce. Příkazem

MyDelegate DDveX=new MyDelegate(DveX);

uděláme zástupce DDveX odkazujícího na funkci DveX. Vyvolání metody pomocí jejího zástupce zapíšeme jménem zástupce následovaným argumenty funkce uzavřenými ve výrazových (kulatých) závorkách. Zástupce též můžeme předat jako parametr při volání nějaké metody.

        Samozřejmě, že můžeme dělat zástupce na statické metody i na metody instance.

        V následujícím programu deklarujeme typ zástupce nazvaný MyDel. Z něho vytváříme v metodě Main dva zástupce f2 a f3 na funkce dvex a trix. Metodu dvex voláme s argumentem 4 pomocí zástupce v příkaze Console.WriteLine(f2(4));. V programu je dále metoda TiskFunkce, které při jejím volání předáváme zástupce na funkci a argument funkce.

 

using System;

namespace Delegates

{delegate float MyDel(float x);

 

 

      class Class1

      {

 

            static void Main(string[] args)

            {

                  MyDel f2=new MyDel(dvex);

                  MyDel f3=new MyDel(trix);

                  Console.WriteLine(f2(4));

                  TiskFunkce(f2,4);

                  TiskFunkce(f3,5);

            }

            static void TiskFunkce(MyDel f,float x)

            {

                  Console.WriteLine(f(x));

            }

            static float dvex(float x){return 2*x;}

            static float trix(float x){return 3*x;}

      }

}

Vícečetní zástupci.

V C# se zástupci používají při deklaraci událostí. Nastane-li v objektu událost, je volána jedna či více metod typu void, které událost obsluhují. Na tyto metody musí mít objekt, v němž událost nastala, reference. K tomu však stačí pouze jeden zástupce odvozený ze třídy Systém.MulticastDelegate. Takovému zástupci budeme říkat zástupce vícečetný.

Nyní si ukážeme základní rysy vícečetných zástupců. Práci s událostmi se budeme věnovat v dalším příspěvku.

Seznam referencí vícečetného  zástupce plníme metodou Combine


public static Delegate Combine(Delegate a, Delegate b);

 

            Pro kompozici zástupců lze navíc v C# s výhodou používat přetížený operátor + (tedy místo metody Combine).

            Metodou Remove


    public static Delegate Remove(Delegate source, Delegate value);

 

lze naopak ze seznamu referencí určitého zástupce source odejmout referenci value. K odstranění zástupce ze seznamu lze navíc v C# s výhodou používat přetížený operátor -.

Seznam referencí umístěných v zástupci lze jeho metodou GetInvocationList načíst do pole typu Delegate. Zdůrazněme, že delegate je klíčové slovo C#, zatímco Delegate je datový typ .NET Framework.

Pomocí vlastnosti zástupce Target lze referencovat objekt, na jehož metodu zástupce ukazuje.

Pomocí vlastnosti zástupce nazvané Metod můžeme získat informace o referencované metodě.

 

    public object Target { get; }
    public MethodInfo Method { get; }

 

Příklad:

Ve třídě CDemo jsou metody Met1 a Met2, podle kterých jsme udělali zástupce Dlg. Dále děláme ze třídy CDemo dva objekty demo1, demo2 a zástupce b který referencuje demo1.Met1 a ještě zástupce c referencující demo1.Met2. Do zástupce a kombinujeme b a c. Následně vytvoříme zástupce d na demo2.Met2 a opět jej vložíme do zástupce a. Potom procházíme cyklem pole delegátů získané voláním metody a.GetInvocationList() a vypisujeme jméno objektu v němž je referencovaná metoda a jméno této metody. Nakonec ze seznamu referencí zástupce a odstraníme referenci b a opět projdeme zbylé reference cyklem.

 

using System;

namespace MultiDelegates

{

      delegate void Dlg(string s);

      class Class1

      {

 

            [STAThread]

            static void Main(string[] args)

            {

                  Dlg a,b,c,d;

                  CDemo demo1=new CDemo("Prvni");

                  CDemo demo2=new CDemo("Druhy");

                  b=new Dlg(demo1.Met1); c=new Dlg(demo1.Met2);

                  a=(Dlg)Delegate.Combine(b, c);

//                a("nazdar");

                  d=new Dlg(demo2.Met2);

                  a+=d;

                  a("nazdar");

                  Console.WriteLine("Procházíme seznam delegátů");

                  Delegate[] dp=a.GetInvocationList();

                  foreach(Delegate di in dp)

                  {

                        Console.WriteLine(di.Target.ToString() + " : " + di.Method.Name);

                  }

                  a=a-b;

                  dp=a.GetInvocationList();

                  Console.WriteLine("Procházíme seznam delegátů po odstranění zástupce b");

                  foreach(Delegate di in dp)

                  {

                        Console.WriteLine(di.Target.ToString() + " : " + di.Method.Name);

                  }

            }

      }

      class CDemo

      {     string name;

            public CDemo(string name)

            {

                  this.name=name;         }

            public void Met1(string s1)

            {

                  Console.WriteLine("Jsem metoda Met1 objektu " + name + " a volali jste mne s parametrem " + s1);

            }

            public void Met2(string s2)

            {

                  Console.WriteLine("Jsem metoda Met2 objektu " + name + " a volali jste mne s parametrem " + s2);

            }

            public override string ToString()

            {

                  return name;

            }

      }

}

Výstup programu:

Jsem metoda Met1 objektu Prvni a volali jste mne s parametrem nazdar

Jsem metoda Met2 objektu Prvni a volali jste mne s parametrem nazdar

Jsem metoda Met2 objektu Druhy a volali jste mne s parametrem nazdar

Procházíme seznam delegátů

Prvni : Met1

Prvni : Met2

Druhy : Met2

Procházíme seznam delegátů po odstranění zástupce b

Prvni : Met2

Druhy : Met2

Autor: Jiří Makovička e-mail: jmakov@natur.cuni.cz web:

Příspěvky ke článku

Méně překladů klíčových slov udělá příspěvek srozumitelnější 25.11.2005 09:57:20 Autor: Vasek
Kde jste slyšel termín "zástupce"? 25.11.2005 09:58:04 Autor: Vašek
Přidat komentář

Poslední ze stejné rubriky

Práce s událostmi v .NET Framework.
Práce s XML v C# (5.) - ověřování dokumentu pomocí třídy XmlValidatingReader
Práce s XML v C# (4.) - třídy XmlDocument a dotazy jazyka XPath
Práce s XML v C# (3.) - třída XmlTextWriter
Práce s XML v C# (2.) - třída XmlTextReader

Funkce ke článku
Přidat komentář

Nejnovější články
Práce s událostmi v .NET Framework. [18094]
Nová soutěž na 3D Contestu CZ [13684]
Práce v .NET Framework - Zástupci [15998]
Práce s XML v C# (5.) - ověřování dokumentu pomocí třídy XmlValidatingReader [14049]
Práce s XML v C# (4.) - třídy XmlDocument a dotazy jazyka XPath [19472]


O článku
Datum: 13.03.2004
Rubrika: DOTNET
Čtenářů: 15998
Autor: Jiří Makovička

Hodnocení článku:
Znamka: 2.86
Počet známek: 3232
[1] [2] [3] [4] [5]

 


(c) Systém Jan Sova, Design David Krásenský a Jan Sova
Se svými dotazy či problémy se obracejte na diskusní fórum.
Časopis je součástí projektu Programator