C # zna dwa warunki delegate
i event
. Zacznijmy od pierwszego.
Delegat
A delegate
jest odniesieniem do metody. Tak jak możesz utworzyć odwołanie do instancji:
MyClass instance = myFactory.GetInstance();
Możesz użyć delegata, aby utworzyć odwołanie do metody:
Action myMethod = myFactory.GetInstance;
Teraz, gdy masz już odwołanie do metody, możesz wywołać metodę za pomocą odwołania:
MyClass instance = myMethod();
Ale dlaczego miałbyś Możesz także zadzwonić myFactory.GetInstance()
bezpośrednio. W takim przypadku możesz. Istnieje jednak wiele przypadków, w których należy zastanowić się, gdzie nie chcesz, aby reszta aplikacji miała wiedzę myFactory
lub do której należy dzwonićmyFactory.GetInstance()
bezpośrednie .
Oczywistym jest jeden, jeśli chcesz być w stanie zastąpić myFactory.GetInstance()
w myOfflineFakeFactory.GetInstance()
jednym centralnym miejscu (aka wzorcem metody fabrycznej ).
Wzór metody fabrycznej
Tak więc, jeśli masz TheOtherClass
klasę i trzeba z niej skorzystać myFactory.GetInstance()
, tak będzie wyglądał kod bez delegatów (musisz poinformować TheOtherClass
o typie twojego myFactory
):
TheOtherClass toc;
//...
toc.SetFactory(myFactory);
class TheOtherClass
{
public void SetFactory(MyFactory factory)
{
// set here
}
}
Jeśli chcesz skorzystać z usług delegatów, nie musisz ujawniać typu mojej fabryki:
TheOtherClass toc;
//...
Action factoryMethod = myFactory.GetInstance;
toc.SetFactoryMethod(factoryMethod);
class TheOtherClass
{
public void SetFactoryMethod(Action factoryMethod)
{
// set here
}
}
W ten sposób możesz przekazać delegata innej klasie do użycia, bez ujawniania im swojego typu. Jedyne, co ujawniasz, to podpis twojej metody (ile masz parametrów i tym podobne).
„Podpis mojej metody”, gdzie to wcześniej słyszałem? O tak, interfejsy !!! interfejsy opisują podpis całej klasy. Pomyśl o delegatach jako o podpisie tylko jednej metody!
Inną dużą różnicą między interfejsem a delegatem jest to, że kiedy piszesz swoją klasę, nie musisz mówić C # „ta metoda implementuje ten typ delegata”. W przypadku interfejsów musisz powiedzieć „ta klasa implementuje ten typ interfejsu”.
Ponadto odwołanie do pełnomocnika może (z pewnymi ograniczeniami, patrz poniżej) odwoływać się do wielu metod (zwanych MulticastDelegate
). Oznacza to, że po wywołaniu delegata zostanie wykonanych wiele jawnie dołączonych metod. Odwołanie do obiektu może zawsze dotyczyć tylko jednego obiektu.
Ograniczenia dla a MulticastDelegate
są takie, że podpis (metoda / delegowanie) nie powinien mieć żadnej wartości zwracanej ( void
) i słów kluczowych out
i ref
nie jest używany w podpisie. Oczywiście nie można wywołać dwóch metod zwracających numer i oczekiwać, że zwrócą ten sam numer. Gdy podpis jest zgodny, delegat jest automatycznie a MulticastDelegate
.
Zdarzenie
Zdarzenia są tylko właściwościami (jak get; set; właściwości pól instancji), które udostępniają uczestnikowi subskrypcję z innych obiektów. Te właściwości nie obsługują jednak funkcji get; set ;. Zamiast tego obsługują dodawanie; usunąć;
Możesz mieć:
Action myField;
public event Action MyProperty
{
add { myField += value; }
remove { myField -= value; }
}
Użycie w interfejsie użytkownika (WinForms, WPF, UWP itd.)
Teraz wiemy, że delegat jest odniesieniem do metody i że możemy zorganizować wydarzenie, aby poinformować świat, że może przekazać nam swoje metody, do których można się odwołać od naszego delegata, a my jesteśmy przyciskiem interfejsu użytkownika: może poprosić każdego, kto jest zainteresowany tym, czy zostałem kliknięty, aby zarejestrować swoją metodę w naszej firmie (za pośrednictwem zdarzenia, które ujawniliśmy). Możemy użyć wszystkich tych metod, które zostały nam przekazane i odwołać się do nich przez naszego delegata. A potem poczekamy i zaczekamy .... dopóki użytkownik nie przyjdzie i nie kliknie tego przycisku, będziemy mieli wystarczający powód, aby wywołać delegata. Ponieważ delegat odwołuje się do wszystkich podanych nam metod, wszystkie te metody zostaną wywołane. Nie wiemy, co robią te metody, ani nie wiemy, która klasa implementuje te metody. Dbamy tylko o to, aby ktoś był zainteresowany kliknięciem przez nas,
Jawa
Języki takie jak Java nie mają delegatów. Zamiast tego używają interfejsów. Robią to, prosząc każdego, kto jest zainteresowany „kliknięciem nas”, o wdrożenie określonego interfejsu (za pomocą określonej metody, którą możemy wywołać), a następnie o przekazanie nam całej instancji, która implementuje interfejs. Prowadzimy listę wszystkich obiektów implementujących ten interfejs i możemy wywołać ich „pewną metodę, którą możemy wywołać” za każdym razem, gdy zostaniemy kliknięci.