Jedna metoda ve ve dvou třídách – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jedna metoda ve ve dvou třídách – .NET – Fórum – Programujte.comJedna metoda ve ve dvou třídách – .NET – Fórum – Programujte.com

 

21. 12. 2021   #1
-
0
-

Ahoj,

potřebuji ve dvou třídách vytvořit metodu public Task AnyName(CancellationToken cancel) která představuje dlouze a asynchronně běžící úlohu. Jak na to?

Pozn.: každá třída je potomkem jiné třídy takže dědičnost (na rozdíl od C++) nepřichází v úvahu. Zatím jsem narazil na pojem rozhraní, ale nevím, jestli je to vhodné pro tento případ.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
JerryM0
Věrný člen
21. 12. 2021   #2
-
0
-

#1 hlucheucho
rozhraní je jenom definice metod, které se musí ve zděděných třídách udělat aby algoritmus fungoval jak má např při řešení problému "dependency injection (DI)"... to s tim nemá nic společnýho leda by si dělal DI asynchronně a to asi neděláš ...

udělat tu tvojí metodu se dá podle příkladu zde:

https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task?view=net-6.0

https://docs.microsoft.com/cs-cz/dotnet/standard/parallel-programming/task-based-asynchronous-programming

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:34dd:9b35:3b82:5627...–
gna
~ Anonymní uživatel
1891 příspěvků
21. 12. 2021   #3
-
0
-

Pokud ti jde o to, aby ty instance byly "zaměnitelné", podobně jako by měly společného předka, tak s interface to jde.

interface INeco
{
    void Metoda();
}

class ChildA: BaseA, INeco
{
    //...
    public void Metoda() { ... }
}

class ChildB: BaseB, INeco
{
    //...
    public void Metoda() { ... }
}


ChildA ca = new ChildA();
ChildB cb = new ChildB();

INeco ia = ca;
INeco ib = cb;
Nahlásit jako SPAM
IP: 213.211.51.–
BDS+3
Věrný člen
21. 12. 2021   #4
-
0
-

#1 hlucheucho
Myslím, že nejvhodnější by bylo, (pokud stávající třídy nejsou zapečetěné a pokud nenarazíš na nějaký jiný problém) vytvořit novou třídu obsahující požadovanou metodu a tuto novou třídu přidat do dědiců obou tříd.

Jak už se tu psalo interface je pouze jakýsi vzor(předpis) jaké metody musí třída obsahovat. Například pokud je třída IComparable musí obsahovat public int CompareTo(object obj)

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
21. 12. 2021   #5
-
0
-

Ono jde spíš o to psát kód metody 1x.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
JerryM0
Věrný člen
21. 12. 2021   #6
-
0
-

ještě taková drobnost nezapomeň do finalizeru třídy uvést ukončení vláken !!! a případně i uvolnění paměti nebo zajisti aby se vlákna ukončily samy

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/finalizers

https://stackoverflow.com/questions/1076965/in-c-sharp-what-is-the-difference-between-a-destructor-and-a-finalize-method-in

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:34dd:9b35:3b82:5627...–
21. 12. 2021   #7
-
0
-

Čekám, kdy někdo napíše: Tak to do jedné třídy napiš a do druhé zkopíruj.

Při ladění to asi budu muset upravit a pak už vtom bude akorát bordel.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
JerryM0
Věrný člen
21. 12. 2021   #8
-
0
-

nekdy je lepší udělat 2 kopie než zmatkovat v jedné složité kopii ... neznáme okolnosti takže ti nepomužu ale ... ... jako nástřel asi bych možná volil tedy static class a static metodu .... tu jedinečnou ... ale to je otázka konkrétní implementace ...
 

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:34dd:9b35:3b82:5627...–
BDS+3
Věrný člen
21. 12. 2021   #9
-
0
-

Ono jde spíš o to psát kód metody 1x.

asi jedině tak jak jsem psal, musíš udělat dědice, který bude navíc obsahovat třídu obsahující to, co potřebuješ.

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
21. 12. 2021   #10
-
0
-

Ještě jeden nápad: Instance obou tříd jsou vloženy do nadřazené třídy. Vytvořit tu metodu v nadřezené třídě a parametrem jí předat objekt se kterým pracuje, něco jako public Task AnyName(Object my_object, CancellationToken cancel)

hu

Nahlásit jako SPAM
IP: 195.178.67.–
BDS+3
Věrný člen
21. 12. 2021   #11
-
0
-

#10 hlucheucho
tak ono záleží na tom, jestli potřebuješ s té metody přistupovat tam nebo tam.. nebo naopak..

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
21. 12. 2021   #12
-
0
-

Nadřazená třída má ty úlohy spouštět, ukončovat a řešit selhání. Akorát to odkázání se na třídu se kterou má pracovat jako Object - není to kostrbatý?

Ráno moudřejší večera.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
BDS+3
Věrný člen
21. 12. 2021   #13
-
0
-

#12 hlucheucho tak to je skoro vždycky..

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
22. 12. 2021   #14
-
0
-

Zvítězila metoda nadřazené třídy a předání pracovní instance pomocí parametru. Vyskytl se problém, jak na Object volat metody instance pracovní třídy. Od použití Object jsem upustil a použil dynamic. Takže metoda nakonec vypadá takto 

public Task AnyName(dynamic my_object, CancellationToken cancel)

hu

Nahlásit jako SPAM
IP: 195.178.67.–
BDS+3
Věrný člen
22. 12. 2021   #15
-
0
-

#14 hlucheucho
Na dynamic jsem narazil poprvé. :)

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
22. 12. 2021   #16
-
0
-

Dobré v případě, že typ objektu zjistíš až za běhu. Přetypování na dynamic je implicitní. Metodu pak voláš jakoby byla metodou třídy dynamic. Takže pak to může vypadat třeba takto 

public Task AnyName(dynamic my_object, CancellationToken cancel)
{
   my_object.object_method();
}

//volani
Task t1 = AnyName(instance_class1, cancel_token);
Task t2 = AnyName(instance_class2, cancel_token);

hu

Nahlásit jako SPAM
IP: 81.19.13.–
BDS+3
Věrný člen
22. 12. 2021   #17
-
0
-

#16 hlucheucho
Díky za info už jsem se na to i trochu díval. Pro tvůj případ se to asi hodí, sám ale nemám představu nač bych to využil...

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
Kit+15
Guru
23. 12. 2021   #18
-
0
-

#1 hlucheucho
Můžeš tu metodu dát do samostatné třídy a provést kompozici do těch dvou tříd.

Nahlásit jako SPAM
IP: 213.175.51.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
23. 12. 2021   #19
-
0
-

#18 Kit
Myslím, že něco v tomto smyslu bylo napsáno ve #4.

hu

Nahlásit jako SPAM
IP: 2001:af0:ffe4:85f4:9d8d:79b1:64f8:c4c...–
Kit+15
Guru
23. 12. 2021   #20
-
0
-

#19 hlucheucho
Ne, tam byla navržena dědičnost - místo toho navrhuji kompozici.

Nahlásit jako SPAM
IP: 46.135.80.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
23. 12. 2021   #21
-
0
-

Neřeší to volání vnořené metody, opět by došlo na dynamic. Vytváření další třídy jen kvůli jedné metodě je dost nešikovné. Navíc když nadřazená třída existuje, obsahuje všechny instance tříd pro které se to řeší a má jim poskytovat "all inclusive".

hu

Nahlásit jako SPAM
IP: 2001:af0:ffe4:85f4:9d8d:79b1:64f8:c4c...–
Kit+15
Guru
24. 12. 2021   #22
-
0
-

#12 hlucheucho
Ta nadřazená třída by tu metodu mohla injektovat do těch instancí.

Nahlásit jako SPAM
IP: 46.135.80.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
BDS+3
Věrný člen
25. 12. 2021   #23
-
0
-

#22 Kit
Udělej nějakou ukázku, prosím.

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
Kit+15
Guru
25. 12. 2021   #24
-
0
-

#23 BDS
Nemá náhodou C# delegáty přesně na tohle?

Nahlásit jako SPAM
IP: 46.135.80.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
BDS+3
Věrný člen
25. 12. 2021   #25
-
0
-

#24 Kit
Navrhuješ s tvého pohledu nejlepší řešení, píšeš o kompozici a injektování. Docela by mě zajímalo to provedení... Uniká mě rozdíl mezi tvým a HU řešením. Jeho řešení si dokážu představit, tvé ne.

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
Kit+15
Guru
25. 12. 2021   #26
-
0
-

#25 BDS
Nevím, jestli by někoho zajímalo mé řešení v PHP.

Nevím ani, zda ty objekty mají společného předka či nikoli, viz první příspěvek.

Nahlásit jako SPAM
IP: 46.135.80.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
25. 12. 2021   #27
-
0
-

#26 Kit
Pozn.: každá třída je potomkem jiné třídy takže dědičnost (na rozdíl od C++) nepřichází v úvahu. Zatím jsem narazil na pojem rozhraní, ale nevím, jestli je to vhodné pro tento případ.

Nemají společného předka.

hu

Nahlásit jako SPAM
IP: 2001:af0:ffe4:85f4:cf2:ba51:fc41:da71...–
25. 12. 2021   #28
-
0
-

Možná má představu, že obě moje třídy budou mít delegáta a jeho prostřednictvím budou volat metodu nadřazené třídy.

hu

Nahlásit jako SPAM
IP: 2001:af0:ffe4:85f4:cf2:ba51:fc41:da71...–
Kit+15
Guru
25. 12. 2021   #29
-
0
-

#28 hlucheucho
Nevím sice přesně, jak funguje delegát (vzor Visitor?), ale možná by se na to hodil.

Nahlásit jako SPAM
IP: 46.135.80.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
BDS+3
Věrný člen
25. 12. 2021   #30
-
0
-

#29 Kit
delegát je v podstatě to samé jako v c++ ukazatel na funkci. Navíc může ukazovat na víc metod. 

Nahlásit jako SPAM
IP: 185.69.68.–
W11 :)
Kit+15
Guru
25. 12. 2021   #31
-
0
-

#30 BDS
Tak to by sedělo. V různých jazycích se tomu říká různě, ale například Java to nemá, ani to nepotřebuje. JS to nazývá callback. V parametrech se předají hodnoty ke zpracování a nemusí se kvůli tomu dělat pochybné accessory.

Nahlásit jako SPAM
IP: 46.135.80.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Matrix17
~ Anonymní uživatel
300 příspěvků
26. 12. 2021   #32
-
0
-

Jinak s tím rozhraním (interface) si nebyl vůbec daleko. Záleží teda v jaké verzi C# to píšeš ale od osmičky už je dostupná default implementaci metody v rozhraní.

https://devblogs.microsoft.com/dotnet/default-implementations-in-interfaces/

Tj. by ti stačilo v obou třídách implementovat nějaké rozhraní, které by mělo definovanou tvou metodu.

Nahlásit jako SPAM
IP: 213.226.237.–
Kit+15
Guru
26. 12. 2021   #33
-
0
-

#32 Matrix17
My se tady dohadujeme, kam tu implementaci umístit tak, aby nevznikla duplicita. Dávat ji do rozhraní mi připadá jako docela hloupé.

Nahlásit jako SPAM
IP: 46.135.80.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
JerryM0
Věrný člen
26. 12. 2021   #34
-
0
-

to co asi hledáte je generická třída :)

https://www.tutorialsteacher.com/csharp/csharp-generics

jednoduše voláte generiku ... v obou větvích, kde na vrvholu stromu je nějaký interface

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:41bd:6c77:7764:5ab6...–
Matrix17
~ Anonymní uživatel
300 příspěvků
27. 12. 2021   #35
-
0
-

#33 Kit
Já to naprosto chápu ale přesně kvůli tomu to je přidaný do Javy i C#. To jestli to je nebo není pěkné je věc zcela jiná. O tom se dá hádat roky. Nicméně je to pro případy, když bys tím rozbil public API a nebo i tento případ.

Ale má to i svá omezení viz. můj koment.

Nahlásit jako SPAM
IP: 213.226.237.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 49 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý