Zdarzenia i pełnomocnicy

Note

Grupy zainteresowań społeczności zostały teraz przeniesione z usługi Yammer do aplikacji Microsoft Viva Engage. Aby dołączyć do społeczności Viva Engage i wziąć udział w najnowszych dyskusjach, wypełnij formularz Żądanie dostępu do aplikacji Finance and Operations Viva Engage Community i wybierz społeczność, którą chcesz dołączyć.

W tym artykule opisano terminologię zdarzeń i słowa kluczowe w języku X++.

Użyj wzorca projektowania zdarzeń, aby kod był bardziej modułowy i wielokrotnego użytku. Termin zdarzenie to metafora, która wyjaśnia, jak są używane delegaty. Jeśli podczas uruchamiania programu wystąpi coś ważnego, inne moduły mogą wymagać przetworzenia wystąpienia. Te ważne wystąpienia są nazywane zdarzeniami. Gdy wystąpi zdarzenie, program informuje jego powiadomienie o zdarzeniu, że powiadomienie musi wysyłać powiadomienia o zdarzeniu. Powiadomienie wysyła powiadomienie do wszystkich programów obsługi zdarzeń, które są subskrybentami powiadomienia. Gdy program poinformuje go o wysłaniu powiadomień, ten proces zgłasza zdarzenie.

Delegata można zdefiniować w tabeli, formularzu lub zapytaniu, a nie tylko w klasie.

W poniższej tabeli przedstawiono terminy opisujące metaforę zdarzenia.

Okres Opis
Zdarzenie Ważne wystąpienie w module programu, w którym dodatkowe moduły muszą przetwarzać wystąpienie.
Powiadomiony Element programu, który wysyła informacje o zdarzeniu do wszystkich programów obsługi zdarzeń, które są subskrybowane do powiadomienia.
Subscriber Funkcje lub metody programu, które są subskrybowane do powiadomienia o zdarzeniach.
Przechwytywacz zdarzeń Metody, które subskrybują powiadomienie o zdarzeniu. Tylko odpowiednie metody mogą być procedurami obsługi zdarzeń.

Słowa kluczowe używane do programowania korzystającego z delegatów

W poniższej tabeli przedstawiono słowa kluczowe opisujące użycie delegatów.

Słowo kluczowe lub termin Code Opis
delegat delegate myDelegate(str information) {} Kod pokazuje, jak wygląda delegat w edytorze kodu. Ponieważ zwracany typ jest zawsze pusty, nie jest wymieniony w składni. Żaden kod nie jest dozwolony wewnątrz nawiasów klamrowych ({}).
eventHandler (program obsługi zdarzeń) myClassInstance.myDelegate += eventHandler(otherClass.myInstanceMethod); Chociaż składnia słowa kluczowego eventHandler może sprawiać wrażenie, że program eventHandler jest funkcją X++, nie jest to funkcja. Słowo kluczowe eventHandler informuje kompilator, że metoda jest subskrybowana do delegata.
Subskrybowanie lub dodawanie metody do delegata myClassInstance.myDelegate += eventHandler(OtherClass::aStaticMethod); W kodzie metoda statyczna OtherClass::aStaticMethod zostaje zasubskrybowana delegatowi.
Wywoływanie delegata myClassInstance.myDelegate("Hello"); To wywołanie delegata monituje delegata o wywołanie każdej metody, która jest subskrybowana do delegata. Subskrybowane metody są wywoływane w tej samej kolejności, w jakiej zostały dodane do delegata. Przed wywołaniem następnej metody przez delegata należy wykonać jedną z subskrybowanych metod.

Example

W poniższym przykładzie kodu pokazano, jak zdefiniować zdarzenie, zasubskrybować zdarzenie i zgłosić zdarzenie przy użyciu dwóch klas. Klasa PointWithEvent definiuje delegata, przeniesiony. Metoda move wywołuje przeniesiony delegat, który powiadamia o wszelkich obiektach, które subskrybują zdarzenie. Klasa PointKeeper definiuje metodę writeMove i przypisuje ją jako procedurę obsługi zdarzeń dla przeniesionego delegata wystąpienia punktu utworzonego w metodzie createAndMove .

class PointWithEvent
{
    // Instance fields.
    real x;
    real y;

    // Constructor to initialize fields x and y.
    void new(real _x, real _y)
    {
        x = _x;
        y = _y;
    }

    void move(real x_offset, real y_offset)
    {
        x += x_offset;
        y += y_offset;
        this.moved(abs(x_offset) + abs(y_offset));
    }

    delegate void moved(real distance)
    {
    }

}

class PointKeeper
{

    public void createAndMove()
    {
        PointWithEvent point = new PointWithEvent(1.0, 2.0);

        point.moved += eventhandler(this.writeMove);

        point.move(4.0, 5.0);
        // Output is "9.0".
    }

    public void writeMove(real distance)
    {
        info(any2Str(distance));
    }

}

Procedury obsługi zdarzeń i metody przed/po

W starszej wersji X++można określić w metadanych, które niektóre metody są wykonywane przed i po wykonaniu metody. Wydawca zarejestrował informacje o wywołaniu subskrypcji, co nie jest przydatne w środowisku. Teraz możesz udostępnić programy obsługi wstępnej i po jej opublikowaniu za pomocą kodu, podając atrybut SubskrybujDo dla subskrybentów.

Przykład metod wstępnych i postów

[PreHandlerFor(classStr(MyClass2), methodstr(MyClass2, publisher))]
public static void PreHandler(XppPrePostArgs arguments)
{
    int arg = arguments.getArg("i");
}

[PostHandlerFor(classStr(MyClass2), methodstr(MyClass2, publisher))]
public static void PostHandler(XppPrePostArgs arguments)
{
    int arg = arguments.getArg("i");
    int retvalFromMethod = arguments.getReturnValue();
}

public int Publisher(int i)
{
    return 1;
}

W tym przykładzie przedstawiono metodę publikowania o nazwie Publisher. Dwóch subskrybentów jest wymienionych przy użyciu atrybutów PreHandlerFor i PostHandlerFor. Kod pokazuje, jak uzyskać dostęp do zmiennych i zwracanych wartości.

Ta funkcja jest udostępniana w celu zapewnienia zgodności z poprzednimi wersjami i, ponieważ kod aplikacji nie ma wielu delegatów, aby opublikować ważne zdarzenia aplikacji. Programy obsługi wstępnej i post mogą łatwo przerwać w wyniku dodanych lub usuniętych parametrów, zmienionych typów parametrów lub dlatego, że metody nie są już wywoływane lub wywoływane w różnych okolicznościach. Atrybuty są również używane do powiązania programów obsługi zdarzeń do delegatów:

[SubscribesTo(
    classstr(FMRentalCheckoutProcessor),
    delegatestr(FMRentalCheckoutProcessor, RentalTransactionAboutTobeFinalizedEvent))]
public static void RentalFinalizedEventHandler(
    FMRental rentalrecord, Struct rentalConfirmation)
{
}

    delegate void RentalTransactionAboutTobeFinalizedEvent(
        FMRental fmrentalrecord, struct RentalConfirmation)
{
}

W tym przypadku atrybut SubscribesTo określa, że metoda RentalFinalizedEventHandler powinna być wywoływana, gdy jest wywoływany delegat FmRentalCheckoutProcessor.RentalTransactionAboutToBeFinalizedEvent. Ponieważ powiązanie między wydawcą a subskrybentami odbywa się za pomocą atrybutów, nie można określić sekwencji, w której są wywoływani subskrybenci.