Megosztás a következőn keresztül:


Meghatalmazottak használata (C# programozási útmutató)

A meghatalmazott olyan típus, amely biztonságosan beágyaz egy metódust, hasonlóan a C és a C++ függvénymutatóhoz. A C függvénymutatókkal ellentétben a meghatalmazottak objektumorientáltak, biztonságosak és biztonságosak. A meghatalmazott típusát a meghatalmazott neve határozza meg. Az alábbi példa deklarál egy elnevezett Callback meghatalmazottat, amely beágyazhat egy olyan metódust, amely argumentumként használ egy sztringet, és érvénytelen értéket ad vissza:

public delegate void Callback(string message);

A delegált objektumokat általában úgy kell létrehozni, hogy megadja annak a metódusnak a nevét, amelyet a meghatalmazott körbefuttat, vagy egy lambda kifejezéssel. A meghatalmazott ilyen módon történő példányosítása után meghívható. A meghatalmazott meghívása meghívja a delegált példányhoz csatolt metódust. A hívó által a delegáltnak átadott paramétereket a rendszer átadja a metódusnak, és a metódusból származó visszatérési értéket a meghatalmazott adja vissza a hívónak. Példa:

// Create a method for a delegate.
public static void DelegateMethod(string message)
{
    Console.WriteLine(message);
}
// Instantiate the delegate.
Callback handler = DelegateMethod;

// Call the delegate.
handler("Hello World");

A delegálttípusok a Delegate .NET osztályából származnak. A delegált típusok lezártak – nem származtathatók belőle, és egyéni osztályok nem származtathatók belőleDelegate. Mivel a példányosított delegált egy objektum, argumentumként átadható, vagy hozzárendelhető egy tulajdonsághoz. Ez lehetővé teszi, hogy egy metódus paraméterként fogadjon el egy meghatalmazottat, és később hívja meg a meghatalmazottat. Ezt aszinkron visszahívásnak nevezzük, és gyakori módszer a hívó értesítésére, ha egy hosszú folyamat befejeződött. Ha ilyen módon használ egy meghatalmazottat, a meghatalmazottat használó kódnak nincs szüksége a használt metódus implementálásának ismeretére. A funkció hasonló a beágyazási felületekhez.

A visszahívások másik gyakori használata az egyéni összehasonlító módszer definiálása és a delegált átadása egy rendezési módszernek. Lehetővé teszi, hogy a hívó kódja a rendezési algoritmus része legyen. Az alábbi példametódus a Del típust használja paraméterként:

public static void MethodWithCallback(int param1, int param2, Callback callback)
{
    callback("The number is: " + (param1 + param2).ToString());
}

Ezután átadhatja a fent létrehozott meghatalmazottat a következő metódusnak:

MethodWithCallback(1, 2, handler);

és fogadja a következő kimenetet a konzolon:

The number is: 3

Ha a meghatalmazottat absztrakcióként használja, MethodWithCallback nem kell közvetlenül meghívnia a konzolt– nem kell a konzolt szem előtt tartania. Egyszerűen MethodWithCallback csak előkészíti a sztringet, és átadja a sztringet egy másik metódusnak. Ez különösen hatékony, mivel a delegált metódusok tetszőleges számú paramétert használhatnak.

Amikor egy példánymetódus körbefuttatására hoz létre meghatalmazottat, a meghatalmazott a példányra és a metódusra is hivatkozik. A meghatalmazottak nem ismerik a példánytípust a körbefuttatási metóduson kívül, így a meghatalmazottak bármilyen típusú objektumra hivatkozhatnak, feltéve, hogy az objektumon található egy metódus, amely megfelel a delegált aláírásnak. Ha egy delegált statikus metódus burkolására van létrehozva, az csak a metódusra hivatkozik. Vegye figyelembe a következő deklarációkat:

public class MethodClass
{
    public void Method1(string message) { }
    public void Method2(string message) { }
}

A korábban bemutatott statikus DelegateMethod mellett most már három metódust is használhatunk, amelyeket egy Del példány becsomagolhat.

A meghatalmazottak meghívásakor több metódust is meghívhatnak. Ezt csoportos küldésnek nevezzük. Ha egy további metódust szeretne hozzáadni a meghatalmazott metóduslistájához – a meghívási listához –, egyszerűen két meghatalmazottat kell hozzáadnia az összeadási vagy összeadási hozzárendelési operátorokkal ('+' vagy '+='). Példa:

var obj = new MethodClass();
Callback d1 = obj.Method1;
Callback d2 = obj.Method2;
Callback d3 = DelegateMethod;

//Both types of assignment are valid.
Callback allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;

Ezen a ponton allMethodsDelegate három metódus szerepel a meghívási listában –Method1Method2 és DelegateMethod. Az eredeti három meghatalmazott d1d2d3változatlan marad. A meghíváskor allMethodsDelegate a rendszer mindhárom metódust sorrendbe rendezi. Ha a meghatalmazott referenciaparamétereket használ, a rendszer egymás után továbbítja a hivatkozást a három metódus mindegyikének, és az egyik metódus módosításai a következő metódus számára láthatók. Ha a metódusok bármelyike olyan kivételt jelez, amely nem szerepel a metódusban, a rendszer átadja a kivételt a meghatalmazott hívójának, és a meghívási listában nem hív meg további metódusokat. Ha a meghatalmazott visszatérési és/vagy kimenő paraméterekkel rendelkezik, akkor az utolsó meghívott metódus visszatérési értékét és paramétereit adja vissza. Ha el szeretne távolítani egy metódust a meghívási listából, használja a kivonási vagy kivonási hozzárendelési operátorokat (- vagy -=). Példa:

//remove Method1
allMethodsDelegate -= d1;

// copy AllMethodsDelegate while removing d2
Callback oneMethodDelegate = allMethodsDelegate - d2;

Mivel a delegálttípusok származtatva System.Delegatevannak, az osztály által definiált metódusok és tulajdonságok meghívhatók a meghatalmazotton. Ha például meg szeretné keresni a metódusok számát a meghatalmazott meghívási listájában, a következőt írhatja:

int invocationCount = d1.GetInvocationList().GetLength(0);

A meghívási listán egynél több metódussal rendelkező meghatalmazottak a következőből MulticastDelegateszármaznak, amely a következő alosztálya System.Delegate: . A fenti kód mindkét esetben működik, mert mindkét osztály támogatja GetInvocationList.

A csoportos küldési meghatalmazottak széles körben használják az eseménykezelést. Az eseményforrás-objektumok eseményértesítéseket küldenek az esemény fogadásához regisztrált címzett objektumoknak. Az eseményre való regisztrációhoz a címzett létrehoz egy metódust, amelyet az esemény kezelésére terveztek, majd létrehoz egy delegáltat ehhez a metódushoz, és átadja a meghatalmazottat az esemény forrásának. A forrás meghívja a meghatalmazottat az esemény bekövetkezésekor. A meghatalmazott ezután meghívja az eseménykezelési módszert a címzetten, és kézbesíti az eseményadatokat. Egy adott esemény delegálási típusát az eseményforrás határozza meg. További információ: Események.

A fordítási időpontban hozzárendelt két különböző típusú meghatalmazott összehasonlítása fordítási hibát eredményez. Ha a delegált példányok statikusan a típushoz tartoznak System.Delegate, akkor az összehasonlítás engedélyezett, de futásidőben hamis értéket ad vissza. Példa:

delegate void Callback1();
delegate void Callback2();

static void method(Callback1 d, Callback2 e, System.Delegate f)
{
    // Compile-time error.
    //Console.WriteLine(d == e);

    // OK at compile-time. False if the run-time type of f
    // is not the same as that of d.
    Console.WriteLine(d == f);
}

Lásd még