Poznáváme C# a Microsoft .NET – 4. díl

Diskuze čtenářů k článku

avatar
24. 11. 2007 13:12

Programovou oflline verzi seriálu naleznete ke stažení na http://poznavame-c-msnet.wz.cz/

Souhlasím  |  Nesouhlasím  |  Odpovědět
Herman  |  01. 10. 2006 09:01

It very interesting oklahoma casino [url=http://xoomer.alice.it/ca777/oklahoma-casino/]oklahoma casino[/url] http://xoomer.alice.it/ca777/oklahoma-casino/

Souhlasím  |  Nesouhlasím  |  Odpovědět
Samantha  |  30. 09. 2006 13:54

Very good website foxwood casino [url=http://xoomer.alice.it/ca777/foxwood-casino/]foxwood casino[/url] http://xoomer.alice.it/ca777/foxwood-casino/

Souhlasím  |  Nesouhlasím  |  Odpovědět
alice  |  28. 09. 2006 16:02

hello, site is cool.

Souhlasím  |  Nesouhlasím  |  Odpovědět
MAno_F., MAno_F.  |  21. 12. 2004 03:24

public int Secti(int a, int b)
{
int vysledek = a + b;
return vysledek;
}

Volání metody by pak probíhalo tímto způsobem:

int soucet = Nazev_tridy.Secti(5,6);


Tak to snad ne! Jedine ze by metoda Secti() byla statickou. Jinak tam musi byt objekt dane tridy (identifikator nebo vyraz vracejici objekt dane tridy) a ne
identifikator tridy samotne.

Metody a konstruktory mohou být v rámci třídy definovány v několika verzích, do kterých vstupuje rozdílný počet parametrů. Takovéto metody/konstruktory jsou nazývány přetížené.

Predpokladam, ze stejne jako v Jave i v C# jdou metody pretizit nejen rozdilnym poctem parametru, ale i rozdilnymi typy parametru (i pri stejnem poctu parametru).

Souhlasím  |  Nesouhlasím  |  Odpovědět
KinDo  |  06. 02. 2006 07:08

nebolo by to ani ako pises ty "Tak to snad ne! Jedine ze by metoda Secti() byla statickou."
to by sa pisalo Nazev_tridy::Secti(5,6);



Souhlasím  |  Nesouhlasím  |  Odpovědět
KinDo  |  06. 02. 2006 11:31

pardon, chyba na mojej strane - tak by to bolo v c++

Souhlasím  |  Nesouhlasím  |  Odpovědět
Benjamin Hejda  |  17. 12. 2004 22:31

"Pokud máme v úmyslu nějakou metodu ve třídě později v odvozených třídách překrývat, musíme tuto metodu nadefinovat jako virtuální. K tomu slouží v C# klíčové slovo virtual."

Zkuste si vyrobit projekt, zkopirovat do nej tyhle dve funkce:
public class Odvozena: BaseTr
{
public override string virtualniFce()
{
return "Odvozena : virtualniFce";
}

public new string nevirtualniFce()
{
return "Odvozena : nevirtualniFce";
}

}

public class BaseTr
{
public virtual String virtualniFce()
{
return "BaseTr : virtualniFce";
}

public String nevirtualniFce()
{
return "BaseTr : nevirtualniFce";
}
}

A do Main zkopirujte tento kod:

BaseTr Zakl = new BaseTr();
Odvozena Odv = new Odvozena();
BaseTr Odkaz = Odv;
Console.WriteLine("Tohle vypise Zakl:");
Console.WriteLine(Zakl.virtualniFce());
Console.WriteLine(Zakl.nevirtualniFce());

Console.W riteLine("Tohle vypise Odv:");
Console.WriteLine(Odv.virtualniFce());
Co nsole.WriteLine(Odv.nevirtualniFce());

Console.Writ eLine("Tohle vypise Odkaz:");
Console.WriteLine(Odkaz.virtualniFce());
Console.WriteLine(Odkaz.nevirtualniFce());
Console.Re adLine();

Abychom mohli nejakou funkci prekryt, NEMUSI byt v predkovi definovana jako virtualni. A nejenom to, obe moznosti - jak virualni, tak nevirtualni funkce maji svoje opodstatneni a rozdil mezi nimi patri k zakladnim poznatkum o OOP.

Taky mam poznamku ke klicovym sloum new a override: V temer 100% pripadu je spravne pouzit slovo override, nebo nepouzit nic a prekladac si ho tam domysli (a vyhodi warning - prekladace nerady premyslej ). Klicove slovo new jako modifikator u virtualni funkce je takova trochu podivna zalezitost a v podstate je v jazyce jenom jako preventivni reseni problemu, ktery ja osobne povazuji spise za hypoteticky.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  18. 12. 2004 14:00

Ještě bych k Vašemu příkladu doplnil, že demonstruje rozdíl mezi (přetěžovaným) překrytím  a stínováním rozhraní rodičovské třídy.
Ve VB.NET by se ukázka zapsala následovně (klíčová slova Overrides a Shadows jsou nepovinná i pro překladač vbc.exe):
 

Class Odvozena: Inherits BaseTr
Overrides Function virtualniFce$()
Return "Odvozena : virtualniFce"
End Function
Shadows Function nevirtualniFce$()
Return "Odvozena : nevirtualniFce"
End Function
End Class
Class BaseTr
Overridable Function virtualniFce$()
Return "BaseTr : virtualniFce"
End Function
Function nevirtualniFce$()
Return "BaseTr : nevirtualniFce"
End Function
End Class

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  19. 12. 2004 03:16

Shadows má stejný význam jako "new" u C#. Je však omyl o těchto klíčových slovech (modifikátorech) hovořit jako o něčem povinném nebo nepovinném. Je to to samé, jako bych řekl, že konstrukt "if (...) {...} else {}" je nepovinný. Když ho do programu vložím nebo nevložím, v obou případech překladač bude spokojen. Jenže to zásadně ovlivní sémantické chování programu. To samé platí i o modifikátoru "override".

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  19. 12. 2004 03:19

A ještě jedno: Překrytí a přetížení jsou úplně odlišné věci.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  19. 12. 2004 14:57

Však o tom právě jako o dvou věcech mluvím a VB.NET je rozlišuje explicitně...
Explicitní deklarace přepisované metody která je současně v odvozené třídě přetěžována ve VB.NET vypadá následovně:
 

  Overrides Overloads Function virtualniFce$()
Return "Odvozena : virtualniFce"
End Function

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  19. 12. 2004 15:53

Nemýlím-li se, tak v tom těchto příkladech se přetížení (overloading) vůbec nevyskytlo neb metody stejných názvů v základní i odvozené třídě mají totožné signatury.

Je ale pravda, že C# explicitní označení pro přetíženou metodu nemá, což uznávám jako malé mínus, protože programátor může přetížit omylem a bez varování překladače. Takže je-li to tak jak říkáte (já bohužel vím o VB. NET kulový má VB.NET malé plus (pokud to slovo "Overloads" vyžaduje).

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  19. 12. 2004 17:21

Ano, pokud nějaké z metod překrývají přetížitelného člena základní třídy, musí být deklarovány jako přetížené klíčovým slovem Overloads a překladač zajišťuje. aby u nevirtuálních metod nedošlo k překrytí metody základní třídy (prvky Overloads a Shadows nelze vzájemně kombinovat).
Z téhož důvodu IDE VS.NET automaticky doplňuje klíčové slovo Overloads při generování kódu jakékoliv přetěžované třídy, takže pokud mezitím dojde ke změně signatury rozhraní v základní třídě, překladač oznámí chybu aniž dojde k jejich (implicitnímu) překrytí.

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  19. 12. 2004 03:09

Obávám, se že autor žádnou chybu neudělal. K vaším výhradám mohu uvést jen toto:

Překrytí (overriding) se již podle definice týká pouze virtuálních metod - viz .NET SDK, klíčové slovo "override modifier" pro jazyk C#. Odtud cituji: "You cannot override a non-virtual or static method". Ve vašem příkladě metoda nevirtualniFce() třídy Odvozena nic nepřekrývá, protože metoda bázové třídy není virtuální.

Poslední odstavec je naprosto nesmyslný. Použití a nepoužití slova "override" má naprosto zásadní význam:

1)
modifikátor "override" ze použít pouze pro překrytí VIRTUÁLNÍ metody.

2)
Pokud v odvozené třídě definujete metodu, jejíž signatura (nepřesně řečeno hlavička) je totožná s nějakou vituální funkcí v některé z bázových tříd (a která není označená jako "sealed"), překladač oznámí varování, zda si přejete virtuální metodu tzv. "skrýt" (hide). Pokud si tak přejete, měl byste jí označit jako new, čímž dáváte překladači najevo, že to není Váš omyl, ale úmysl. V opačném případě vás varuje, ale kód je přeložen, jako kdyby tam "new" bylo. "new" tedy není od toho, aby řešilo nějaký problém, ale od toho, abyste jako autor potvrdil svůj úmysl skrýt virtuální funkci.

O "skrytí" nebo "překrytí" lze mluvit pouze u virtuálních metod a je nutné bezpodmínečně chápat rozdíl. Pokud v odvozené třídě použijeme metodu se stejnou signaturou jako má nevirtuální metoda v bázové třídě, ani jeden z těchto pojmů nelze použít, protože se v dědičné hierarchii pro takovou metodu neuplatňuje polymorfismus.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  19. 12. 2004 16:12

Snad bychom se mohli vzájemně domluvit na názvosloví, kdy termín přepisování zahrnuje jak překrývání, tak skrývání ("hide by signature") virtuálních funkcí a stínování pro skrývání těch ostatních - pak máte pravdu stejně jako Petr Pecha. Bez zavedení této terminologie si však trochu odporujete v tvrzení
..pokud v odvozené třídě použijeme metodu se stejnou signaturou jako má nevirtuální metoda v bázové třídě, ani jeden z těchto pojmů nelze použít....
protože C# v tom případě uplatňuje (implicitně) klíčové slovo new  (resp. VB.NET shadows) úplně stejně, jako v případě skrývání (ačkoliv se zde, jak uvádíte, neuplatňuje polymorfismus).
Celá tato legrace slouží např. pro rozlišení situací, kdy si přepíšete nějakou metodu v knihovně, jejíž autor mezitím udělá totéž - ovšem jiným způsobem. Pak se budete muset rozhodnout, zda ze své odvozené třídy budete volat jeho či svoji variantu.

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  19. 12. 2004 17:11

Já vím, jak to pan Petr Pecha myslel. Jde jen o to, že terminologie pro C# je daná, a to Microsoftem. Snad beze sporu je také zřejmé, že ve VB.NET mohou být stejné věci nazývány jinak. To je také dané Microsoftem. Zářným příkladem ryze terminologického rozdílu C# vs. VB.NET je je modifikátor "new" v C# a klíčové slovo "Shadows" ve VB.NET.

K té mé odporující si větě: Máte pravdu, omlouvám se a děkuji za upozornění. Proto má poslední věta platí pouze pro překrytí (override) a nikoli skrytí. Skrytí opravdu nesouvisí s polymorfismem, ale pouze s dědičností.

Jinak obecně jsem zastáncem, toho, že by se měla dodržovat terminologie přesně tak, jak byla zavedana autorem jazyka. V opačném případě může být čtenář dost zmaten již třeba nahlédnutím do SDK. Proto by se v seriálu o C# vůbec nemělo vyskytnout stínování (Shadows).

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  19. 12. 2004 18:10

Pokud skrytí nesouvisí s polymorfismem, pak je název odstavce Virtuální metody a jejich překrytí pomocí new a override v článku přece jen trochu zavádějící, protože klíčové slovo new se vztahuje ke skrytí, nikoliv překrytí (v duchu Vaší terminologie), což byl patrně příčina výroku čtenáře Hejdy "Abychom mohli nejakou funkci prekryt, NEMUSI byt v predkovi definovana jako virtualni." Zdá se tedy, že se jisté nepřesnosti na počátku dopustil každý z nás, ale věřím, že diskuse přispěla k vzájemnému ujasnění pojmů.
Z téhož důvodu bych si dovolil malinko upřesnit výrok z článku "privátní členy se nedědí a bylo by nutné tento atribut ve všech třídách znovu deklarovat" Jde o běžně citovaný omyl - protože ony se dědí, jen k nim nemusí být z odvozených tříd veřejný přístup - jinak by totiž nemohla fungovat ukázka níže. S ohledem na terminologickou konzitenci C# bych se také přimlouval za nepoužívání pojmu atribut  ve významu field (vím, že se členům tříd tak v C++ a Delphi říká, ale pojmu attribut je v C# vyhražen deklarátor metadat, jak na to již bylo upozorněno výše). Ale to jsou v zásadě jen drobné terminologické detaily...
 
public class MyClass{
 public static void Main() {
  CChild C = new CChild();
     System.Console.Write(C.Test());
 }
    class CBase    {
     private string clen = "Just mine";
     public string Test()      {
       return clen;
     }
    }
    class CChild : CBase {}
}

 
Syntaktické rozdíly v pojmenování atributů ve VB.NET a C# jsou opravdu malý rébus, jmenovitě klíčové slovo static, které se používá jak ve VB.NET, tak C#, ale pokaždé v jiném kontextu. V tomto ohledu se dovoluji odkázat na MS PSS White Paper, kde jsou rozdíly shrnuty v přehledné tabulkové formě.
 
http://download.microsoft.com/download/visualstudionet/document/1.0/win98mexp/en-us/vbcsharpwp.exe

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  19. 12. 2004 19:04

Dobrá reakce. Přiznávám se, že jsem reagoval na příspěvky, aniž bych si vůbec důkladně přečetl původní článek. Myslím, že je vše vyjasněno. Rovněž se přimlouvám za nahrazení pojmu atribut. Atribut je obvykle pojem v konceptuálních modelech (např. UML, E-R). Autor asi chtěl hladce navázat na svá UML schémata, ale myslím, že to je spíše méně vhodné.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Benjamin Hejda  |  19. 12. 2004 22:29

Taky jsem rad, ze jsem prisel na svuj omyl - ja jsem si fakt myslel, ze pri prepisovani virtualni metody v potomkovi se automaticky predpoklada, ze ji chci prekryt a ne skryt. Tento muj omyl ovsem nikdy nezpusobil chybu, a to proto, ze se zasadne snazim psat kod bez warningu, kdykoliv je to jen trochu mozne a znovu se ukazalo, ze to je spravny pristup. Na druhou stranu nic to nemeni na tom, co jsem chtel rict, a to, ze nepovazuju za dobry napad virtualni metody ve zdedenych tridach skryvat a ne prekryvat. Ve skutecnosti je to napad velmi hloupy - protoze takova vec jde jasne proti smyslu virtualnich metod. A vlastne moznost tohle udelat neni v C# proto, ze by melo byt bezne takhle psat, ale proto, ze teoreticky muze dojit k takoveto situaci: Ja pouzivam nejakou externi knihovnu, zdedim si z ni nejakou tridu a v tom potomkovi vyrobim novou virtualni metodu. Pak se ale stane, ze v nove verzi knihovny jeji autor pride do te tridy, kterou ja pouzivam jako bazovou, virtualni metodu stejneho jmena (ackoliv i pri pomerne letmem rozboru tehle situaci je jasne, ze klicove slovo new tuhle situaci stejne nezachrani).

2 Petrik: "Ctenar Hejda" - to zni priserne. Mohl byste psat proste Benjamin?

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  19. 12. 2004 23:20

Mohl, čten... Benjamine...
Překrytí funkce v přepsání virtuální metody jistě nezabrání, ale v případě, že používáte v odvozené třídě metodu téhož jména vám umožní vytvořit třídu s metodou, která se odkazuje na ni, místo na původní virtuální metodu rodiče. Když tedy autor knihovny do své knihovny připíše červený kód, vy dopíšete ten brčálově zelený...
 

using System; 
class CPolymorphDemo {
static void Main() {
CChildOvd COvd = new CChildOvd();
CChildShd CShd = new CChildShd();
Console.WriteLine(COvd.virtMetoda());
Console.WriteLine(CShd.virtMetoda());
}
}
class CChildOvd : CBase {
public override string virtMetoda() {
return " CChild : překrytá virtMetoda";
}
string virtMetoda(object s) {
return " CChild : překrytá virtMetoda";
}
}
class CChildShd : CBase {
new string virtMetoda() {
return " CChild: skrytá virtMetoda";
}
}
class CBase {
public virtual string virtMetoda() {
return " CBase: virtMetoda";
}
public virtual string virtMetoda(string s) {
return " CBase: virtMetoda";
}
}

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  20. 12. 2004 03:04

Ta brčálově zelená "string virtMetoda(object s)" není překrytá, nýbrž přetížená.

Ještě se pokusím o souhrn těch tří pojmů:

1) Překrytí (modifikátor "override")
Souvisí výhradně s polymorfismem, který dosud v článku nebyl vysvětlen. Autor se možná měl zatím virtuálním metodám zcela vyhnout, poněvadž představovat virtuální metody bez polymorfismu je nesmysl. Virtuální metody jsou totiž nástrojem polymorfismu.

2) Skrytí (modifikátor "new")
Souvisí s dědičností i s polymorfismem. Opět by se o tom lépe diskutovalo po vysvětlení polymorfismu a na příkladech. Jinak doporučuji na odstavec "Virtuální metody a jejich překrytí pomocí new a override" raději zapomenout.

3) Přetížení
Definování metody, jejíž název je shodný s jakoukoli existující metodou v celé třídní hierarchii uvažované třídy. Tato nově definovaná metoda se liší od té definované svými parametry.

Doufám, že autor v příštím díle v souvislosti s polymorfismem uvede věci na pravou míru a rozebere pojmy skrytí a překrytí (přetížení už vysvětlil). Teď už je mi jasné, proč Benjamin namítnul to, co namítnul (a zcela oprávněně). Jenže citoval zrovna větu, která při vytržení z kontextu byla sama o sobě správná.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  20. 12. 2004 03:40

není překrytá, nýbrž přetížená  Bohužel jsem zapomněl opravit copy&paste řádek, čímž se stal příklad spíš matoucí, než vysvětlující...
Namísto toho zmateného barvení kódu jsem tedy zkusil sestavit stručný příklad té situace, kdy si změna rozhraní v bázové třídě může vynutit skrytí (resp. stínování, resp. předefinování) jejího rozhraní. Jinak je to z hlediska čistoty OOP obskurita, v normální situaci není k takovému porušování dědičnosti důvod, za předpokladu, že v rodičovské třídě jsou metody definovány jako virtuální. Možná se mi časem podaří najít ještě nejaký vhodnější příklad.
 
http://vbnet.aspweb.cz/vbnet/shadowing.htm

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  20. 12. 2004 04:08

..o "skrytí" nebo "překrytí" lze mluvit pouze u virtuálních metod .... ..skrytí (modifikátor "new") souvisí s dědičností i s polymorfismem.
Spíše bych se přidržel Vašeho původního tvrzení ("skrytí nesouvisí s polymorfismem, pouze s dědičností") - technicky lze totiž skrývání uplatnit na libovolné rozhraní bez vztahu k polymorfismu a virtuálním členům rozhraní (čímž se také od přepisování pomocí inheritance liší):
 

using System;
public class CChild : CBase {
new static string x = "test"; // předefinování rozhraní základní třídy vč. typu
static void Main() {
Console.WriteLine(x); // zobrazení nové hodnoty x:
Console.WriteLine(CBase.x); // přístup ke skrytému rozhraní:
}
}
public class CBase {
public static int x = 1;
}

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petr Mach  |  21. 01. 2005 10:45

Z téhož důvodu bych si dovolil malinko upřesnit výrok z článku "privátní členy se nedědí a bylo by nutné tento atribut ve všech třídách znovu deklarovat" Jde o běžně citovaný omyl - protože ony se dědí, jen k nim nemusí být z odvozených tříd veřejný přístup - jinak by totiž nemohla fungovat ukázka níže.

O omyl jde, ale na tve strane. Privatni cleny se nededi. Proto nejsou pristupne. Tva ukazka ukazuje, ze si pletes tridy s instancemi. Ve tride privatni clen nadrazene tridy nenajdes. Krom toho, ty v instanci odvozene tridy pouzivas jeji verejny clen.

Viz treba:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vjref98/html/8_2.asp
http://www.uni-bonn.de/~manfear/javaprotection.php
http://www.cs.jcu.edu.au/Subjects/cp2003/1998/ch7Type/inheritance.html
http://www.cprogramming.com/tutorial/lesson20.html
http://javapronews.com/javapronews-47-20020319C-Inheritance-for-Java-Programmers.htm l
http://www.cs.uregina.ca/Links/class-info/170/inherit.html
http://www.jguru.com/forums/view.jsp?EID=1215726

Souhlasím  |  Nesouhlasím  |  Odpovědět
MAno_F., MAno_F.  |  21. 12. 2004 02:49

Takze pokud B je potomkem A a obe tridy definuji metodu metoda() se stejnou signaturou, jen v A je opatrena modifikatorem virtual a v B modifikatorem new, tak

B b = new B();
A a = b;
a.metoda();
b.metoda();

se vyvolaji dve ruzne metody?
Pokud ano, tak to dela docela nechutny bordel v polymorfismu a pak se nemuzu spolehnout na to,
ze vyvolani metody se stejnou signaturou na stejnem objektu (k nemuz pristupuji nejdriv pres jeho
predka a pak pres jeho vlastni specializovanou tridu) vyvola stejnou metodu. Z toho se mi dela spatne.

Rozumim tomu spravne?

Souhlasím  |  Nesouhlasím  |  Odpovědět
MAno_F., MAno_F.  |  21. 12. 2004 03:12

Jeste jedna otazka:

Kdyz B je potomkem A a metoda metoda() v A neni virtualni a v B ji ani neprekryvam ani neskryvam, tak

// 1.
A a = new A();
a.metoda();

je v pohode, ale

// 2.
A a = new B();
a.metoda();

uz v pohode neni? Anebo neni v pohode jen

// 3.
B b = new B();
b.metoda();

? Pokud by (2.) proslo a (3.) ne, tak je to dost drsny, protoze pak bych pro volani metody metoda() musel uzit pretypovani. Pokud by neproslo ani (2.) tak je to jeste horsi, protoze vubec nemuzu vedet,
jestli a.metoda() zavolat muzu nebo nemuzu (pokud napr. a je parametrem nejake jine metody).

Zaplatpanbuh za Javu, kde jsou vsechny nestaticke metody implicitne virtualni (final sice nejde zmenit, ale dedi se taky). Alespon jsem usetren takovych problemu. A z diskuse je videt, ze to programatory silne mate a ideu OOP to silne prasi.

Souhlasím  |  Nesouhlasím  |  Odpovědět
MAno_F., MAno_F.  |  21. 12. 2004 03:15

Zaplatpanbuh za Javu, kde jsou vsechny nestaticke metody implicitne virtualni (final sice nejde zmenit, ale dedi se taky). Alespon jsem usetren takovych problemu. A z diskuse je videt, ze to programatory silne mate a ideu OOP to silne prasi.

Napsal jsem to spatne, ale chtel jsem napsat, ze koncepce C# (ne koncepce Javy) je matouci a prasi OOP.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik, Petrik  |  21. 12. 2004 08:56

Jasně, předefinování virtuálních metod porušuje substituční princip inheritance (tzv. pravidlo Liskovové - metody základní třídy mají mít přístup k objektům odvozených tříd) - na druhou stranu dává využívání odvozených tříd potřebnou flexibilitu v případě, že se změní rozhraní základní třídy. Ale také bych se přimlouval za to, aby nestatické metody byly implicitně virtuální.
 
http://c2.com/cgi/wiki?LiskovSubstitutionPrinciple

Souhlasím  |  Nesouhlasím  |  Odpovědět
Benjamin Hejda  |  21. 12. 2004 09:46

Vsechno troji je samozrejmne v poradku a bude se to chovat stejne, jako by se to chovalo v Jave. Uplne standardni chovani ma i dedeni a prepisovani virtualnich metod, pokud v potomkovi nepouzijes modifikator new. Ten modifikator new je vec, kterou Java nema a je to trochu podivna zalezitost, jak uz jsem psal. Na druhou stranu nikdo te nenuti ho pouzivat.
To co mi vadilo byl pristup, ktery autor zvolil: Drive nez poradne vysvetlil rozdil mezi virtualnimi a nevirtualnimi metodami, zacne ctenare mast s rozdilem mezi override a new, navic formou jakesi "kucharky", coz je vec, na kterou jsem proste alergicky, protoze sice chapu, ze vysvetlovat OOP nemusi byt zrovna snadne, ale kdyz uz se do toho nekdo pusti, ma to udelat poradne a ne napul. Rozlisovat override a new primarne podle toho, jestli metoda v potomkovi plni stejnou nebo jinou funkci je prece nesmysl. Programator, ktery vedomne ,a prestoze ho k tomu nikdo nenuti, napise do potomka metodu stejneho jmena, jako je v predkovi, ale s uplne jinou funkcnosti je proste vul.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik, Petrik  |  21. 12. 2004 10:42

...bude se to chovat stejne, jako by se to chovalo v Jave...
 
V Javě jsou metody virtuální by_default, tzn. je nutné je překrýt. Rozdílem .NET oproti Javě je také v implicitní skrytí metod v odvozené třídě, pokud se liší signaturou. Pokud např. překladači předložíte novou verzi knihovny s bázovou třídou, jediné co provede je, že kvikne varování, že by bylo vhodné klíčové slovo new doplnit a doplní ho sám. Pokud máte při překladu vypnutá varování úrovně 4 a 5, nemusíte si předefinování metody vůbec všimnout. V tomto ohledu se dokonce liší přístup ke stínování mezi VB.NET a C# : skrývané metody v C# mohou předefinovat pouze úroveň přístupu a návratový typ, prostředí VB.NET s OOP zachází ještě mnohem volněji a z původní metody umožňuje ponechat jen jméno.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik, Petrik  |  21. 12. 2004 10:58

ale s uplne jinou funkcnosti je proste vul
 
Nejde o funkčnost, ale o signaturu. Pokud je předek v knihovně třetí strany které se při upgrade změní rozhraní, pak jde o situaci, kterou programátor při sebelepší vůli neovlivní a měl by na ni být naopak upozorněn. Microsoft si tímto přístupem v prostředí .NET evidentně v tomto směru ponechává volnou ruku vůči dalším změnám rozhraní do budoucnu - aplikace díky implicitnímu skrývání přetěžovaných metod nejenom poběží, ale dokonce půjdou i bez nutnosti úpravy zkompilovat, ačkoliv metody v knihovně nepřekrývají, ale předefinovávají! Čili logiku to má, ovšem na úkor čistoty principů OOP - není to poprvé a naposledy, kdy abstraktní čistota návrhu ustoupila praktickým hlediskům.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Benjamin  |  21. 12. 2004 15:21

Me ani tak neslo o to, jestli je dobre, ze tento prvek v C# je, nebo neni. Problem je v tom, ze v clanku je pouzivani kl. slova new u prepisovanych virt. metod prezentovano jako uplne normalni vec.

Souhlasím  |  Nesouhlasím  |  Odpovědět
MAno_F., MAno_F.  |  21. 12. 2004 14:16

Takze pokud tomu spravne rozumim, nevirtualni metoda se chova jako final v Jave. T.j. nejde prekryt.

Pokud ale (narozdil od Javy) jde skryt, pak je to opravdu prasarna, protoze


public class A {
void metoda() {
//...
}
//...
}

public class B: A {
new void metoda() {
//...
}
//...
}

//...
B b = new B();
A a = b;
b.metoda();
a.metoda();


jsou volani dvou ruznych metod, ackoliv se stejnou signaturou na stejnem objektu.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Benjamin  |  21. 12. 2004 14:54

Ja nevim, co v tom vidis za prasarnu. Existence nevirtualnich metod proste do OOP patri a od svych virtualnich kolegyn se lisi prave tim, ze se vybiraji podle toho, jakeho typu je odkaz na ne. Aniz bych se chtel poustet do nejakeho flamu, tak si troufnu rict, ze pokud Java nema pro instance jine, nez virtualni metody, tak umi jednoznacne mene, nez C#.

Souhlasím  |  Nesouhlasím  |  Odpovědět
MAno_F., MAno_F.  |  22. 12. 2004 13:30

Mene je nekdy vice

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik, Petrik  |  21. 12. 2004 16:00

 ...pak je to opravdu prasarna, protoze...
To je věc diskuse. Dejme tomu, že používáte knihovnu, obsahující tuto bázovou třídu:

class A  {
private int i;
public void f(int ii){}
};
Dejme tomu, že si knihovnu vylepšíte a tuto metodu přetížíte, např. následovně:
class B: A {
public void f(long ii, string s)
};

a používáte třeba takto  (s vědomím faktu, že int se na long přetypuje implicitně):
char* s = "Hello";
int i=3;
b.f(i,s);

Jednoho krásného dne ale autor bez vašeho vědomí přetíží metodu ve své knihovně sám následovně:
class A  {
private int i;
public void f(int ii) {}
public void f(int ii, string s){}
};
Vy si novou knihovnu stáhnete a začnete používat jako předtím Jelikož Vaše dosavadní volání odpovídá signatuře nového přetížení přetížení lépe, znamenalo by to současně, že by jste začal volat přetíženou metodu v základní třídě, aniž by jste to tušil a Váš program by začal potenciálně vracet jiné výsledky! V daném případě by bylo zjevně mnohem vhodnější, kdyby překladač použil Vaši metodu v odvozené třídě a přetíženou metodu základní třídy skryl implicitně. A právě tak se chová C# a VB.NET.
Ve skutečnosti dokonce ani žádné klíčové slovo new psát nemusíte, C# jej předpokládá implicitně, pokud si výslovně nepožádáte o přetížení modifikátorem override , jen Vás upozorní varováním překladače. Jde sice o zjevné porušení inheritance, které by jste Vy sám záměrně zneužívat neměl - nicméně představte si, že svým klientům distribuujete knihovnu s třídou odvozenou od bázové třídy z knihovny třetí strany. Pak jejího autora napadne knihovnu upravit, Vaši klienti stáhnou její upgrade a v tom okamžiku přestane Vaše knihovna fungovat, protože se obsahuje metody přepisující neexistující rozhraní, nebo (pokud obsahuje Vaše vlastní metody se stejnou signaturou) - začne je používat bez Vašeho vědomí, což je ještě horší.
 
Fakt, že při změně kódu stačí provést změnu v základní třídě na jednom místě se snadno obrátí proti Vám v případě, že nespravujete odvozené třídy současně. Stínování tento nedostatek inheritance obchází.

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  21. 12. 2004 18:18


...V daném případě by bylo zjevně mnohem vhodnější, kdyby překladač použil Vaši metodu
v odvozené třídě a přetíženou metodu základní třídy skryl implicitně. A právě tak
se chová C# a VB.NET.


Překladač ale neprovádí žádné implicitní skrytí. Překladač provádí pouze implicitní typovou
konverzi parametru i z int na long. Toto chování je
jeho nástrojem na řešení diskutované kolize. Takže jde o implicitní přetypování a nikoli skrytí.



...Ve skutečnosti dokonce ani žádné klíčové slovo new psát nemusíte, C# jej předpokládá implicitně.


Nepředpokládá. Dejte tam new explicitně a překladač hodí varování, že ho není třeba, neb

metoda nic neskrývá.



...pokud si výslovně nepožádáte o přetížení modifikátorem override , jen Vás upozorní varováním překladače.


Modifikátor override nepřetěžuje, nýbrž překrývá a s tímto příkladem vůbec nesouvisí.


...Vaši klienti stáhnou její upgrade a v tom okamžiku přestane Vaše knihovna fungovat, protože se obsahuje

metody přepisující neexistující rozhraní, nebo (pokud obsahuje Vaše vlastní metody se stejnou signaturou) -

začne je používat bez Vašeho vědomí, což je ještě horší.


Řešení tohoto a jiných problémů řeší .NET správou assemblies a jejich verzí. Není problém umožnit aplikaci

pracovat pouze s knihovnou pevně dané verze.

Jinak má podle mě s tou prasárnou Benjamín úplně pravdu - totiž, že by neměly existovat v jedné
větvi třídní hierarchie dvě metody, mezi nimiž je přerušená inheritance. Označení prasárna
je výstižný, protože to vede to k nepřehlednosti.

Kolizí názvů se má předcházet výstižnými názvy. Pokud kolize nastane, autor odvozených tříd by měl použít
refaktoring. Až pokud z praktických důvodů nelze tyto metody použít, pak se holt musím smířit se snížením
přehlednosti (prasárnou). Každopádně by k tomu nemělo dojít, pokud celou třídní hierarchii spravuje jeden
vývojový tým. Pokud ovšem existuje celá řada na sebe navazujících knihoven od různých výrobců a tito
výrobci používají špatně pojmenovávací konvence, tak tomu asi s jistotou předejít nelze.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik, Petrik  |  21. 12. 2004 19:41

...jde o implicitní přetypování a nikoli skrytí...
Reaguji na příspěvek z 21.12.2004 14:16 ("dvě různé metody se stejnou signaturou"). Pokud neuvedu způsob přepisování, překladač sám od sebe skryje metodu v bázové třídě. Nemusíte to nijak zjišťovat, sám Vám to při překladu oznámí:
 

 
...nepožádáte o přetížení modifikátorem ...Modifikátor override nepřetěžuje   Jasně, to bylo přeřeknutí, jsem přetížený...

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  21. 12. 2004 21:06

V tomto případě opravdu jde o skrytí. V tom předchozím však o skrytí nešlo, protože se lišily signatury:


public void f(long ii, string s) // ve třídě B
public void f(int ii, string s) // později dodaná metoda do třídy A


Já reagoval na váš příspěvek. V příspěvku z 21.12.2004 14:16 o skrytí opravdu šlo.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik, Petrik  |  21. 12. 2004 19:49

Není problém umožnit aplikaci pracovat pouze s knihovnou pevně dané verze.
 
Jde o to, co se stane, když knihovnu upgradeujete úmyslně (třeba proto, že obsahuje opravy chyb, nebo novou funkcionalitu), a ona najednou obsahuje nové metody se signaturou, kterou jste mezitím implementoval sám. Na tom není nic nekorektního - znamená to prostě, že autor mezitím implementoval stejný nápad, jako vy a je to vlastně docela reálná situace.

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  21. 12. 2004 21:26

To je pravda, ale transparentně se to stát nemůže. Admin musí dovolit použití "neschválené" knihovny (assembly), čímž dobrovolně podstupuje riziko problémů.
Pokud však kontaktuje autora a ten to dostane pod překladač, tak ten překladač vyhodí varování a autor může provést korekci.

Ano, nekorektního na tom nic není, ale prasárna to je. Reálně to nastat může, ale v
kvalitních návrzích to prakticky nehrozí. Pokud se jedná o případ stejného nápadu, kdy
to autor bázové třídy to doimplementuje později, tak to v potomkovi můžu s klidem
zrušit (nebo upravit překrytím, je-li metoda virtuální).

Ještě jiná slova:
Prasárna to je proto, že jedna funkčnost je implementována redundantně - byl-li to stejný nápad a má tedy sloužit stejnému účelu. Pokud se nejedná o stejný účel, není důvod, proč by se v potomkovi metoda nemohla jmenovat jinak, což k přehlednosti jedině prospěje.

Jedním dechem dodávám, že někdy je z různých důvodů nutné prasárny dělat, dělám je taky, hlavně když koriguji prasárny někoho jiného.

Souhlasím  |  Nesouhlasím  |  Odpovědět
MAno_F., MAno_F.  |  22. 12. 2004 14:08

Tato hypoteticka situace je sice mozna ale rekl bych, ze vysoce nepravdepodobna. Za vic nez 3 roky co delam s Javou se mi to nestalo ani jednou.

Taky je silne pravdepodobne, ze metody se stejnou signaturou budou delat v principu stejnou vec jak v bazove tride, tak v odvozene.

A pokud se autor bazove tridy chce spolehnout na to, ze jeho metoda nebude zmenena a porad bude delat to, co on chce, tak ji jednoduse udela final a pak ta odvozena trida neprojde. Nelze prekryt final metodu.

Nicmene, silne se doporucuje poradne se zamyslet, jestli pouzit dedicnost a ne radsi kompozici. Pouziti dedicnosti
ma potencialne nekolik neblahych dusledku. To se projevilo v Jave napr. i v standardni tride java.util.Properties,
jez je potomkem java.util.Hashtable. Jeden z dusledku je, ze ackoliv realne Properties by meli mit jak klice, tak prirazene hodnoty pouze typu String, tak z dedicnosti z Hashtable plyne, ze musi byt i jakykoliv Object. Taky nelze
zamenit (kvuli zpetne kompatibilite) predka Properties za jinou implementaci interface Map. O co bezproblemovejsi by
bylo udelat prislusnou implementaci Map jen fieldem v Properties (navic jeste private) a to, co se hodi, delegovat
na tento field a zbyle veci si implementovat po svym...

Jiny priklad:


class Point {
int x;
int y;
Point(int pX, int pY){
x = pX;
y = pY;
}
bool equals(Point pPoint) {
return((pPoint != null) && (pPoint.x == x) && (pPoint.y == y));
}
}

class ColoredPoint: Point {
int color;
ColoredPoint(int pX, int pY, int pColor){
base(pX, pY);
color = pColor;
}
bool equals(Point pPoint) {
return((pPoint != null) && (pPoint.x == x) && (pPoint.y == y) &&
(((ColoredPoint) pPoint).color == color));
}
}

//...

Point point = new Point(12, 30);
Point point2 = new ColoredPoint(12, 30, 10);
bool a = point.equals(point2);
bool b = point2.equals(point);


Diky blbe zvolene dedicnosti bude a == true (ackoliv bezbarevny bod neni roven barevnemu bodu na stejnem miste),
a b se ani nevypocte, protoze to shori na ClassCastException (nebo jak se to jmenuje v C#).

Nic proti dedicnosti, je to opravdu silny nastroj, ale pokud je to jakkoliv mozne, vyhnete se dedeni z konkretnich
trid, protoze to ma neblahe nasledky. Dedicnost je naopak skvela pri hierarchii trid a rozhrani, kde jen posledni
(nejspecialnejsi) tridy jsou konkretni, jinak jsou vsichni predci abstraktni (anebo rozhrani). Rozhodne je lepsi
implementovat interface nez dedit (pokud ovsem neni vnitrni implementace bazove tridy pevne dana a nemenna - coz
byva malokdy).

Takze ano, hypoteticky by nekdy mohla C# implementace OOP byt vyhodnejsi nez Java, avsak takovych pripadu
je tak malo, ze nevyhody (necistota OOP a moznost nechutne sprasit kod) silne prevazuji. Alespon pro me.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Alex  |  22. 12. 2004 19:52

tato hypoteticka situace je sice mozna ale rekl bych, ze vysoce nepravdepodobna ..  ...pokud ovsem neni vnitrni implementace bazove tridy pevne dana a nemenna - coz byva malokdy...
 
Skrytí metody bázové třídy slouží právě jako pojistka pro případ, že se změní implementace bázové třídy způsobem, který nemůžete ovlivnit... 
Jinak stran Vašich preferencí kompozice na úkor inheritance lze jen souhlasit.. v každém seriálu, věnovaném OOP by bylo vhodné uvést případy, kdy je vhodné dědit a kdy je vhodné použít rozhraní.

Souhlasím  |  Nesouhlasím  |  Odpovědět
lhs  |  17. 12. 2004 17:51

'Autoři jazyka C# se ale několikanásobné dědičnosti vyvarovali, kvůli problémům, které při jejím užívání vznikaly.'

Tato veta na me pusobi jako typicky FUD, Muzete byt konkretni a mene strasit ctenare? Ne ze bych nasobnou vzdy nutne potreboval, ale nekdy se hodi. Proc nemit objekt, ktery dedi napr. po objektu animovatelny a take po objektu pohybovatelny.

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  17. 12. 2004 21:49

"Strašení" je na místě, viz např.

http://www.builder.cz/art/homepage/cpp_vicededic.html

C# (.NET Framework) však podporuje tzv. "rozhraní", kterými lze nahradit funkcionalitu vícenásobné dědičnosti. V jedné třídě pak lze implementovat více rozhraní.

Souhlasím  |  Nesouhlasím  |  Odpovědět
lhs  |  18. 12. 2004 21:10

Netvrdim, ze je vicenasobna dedicnost zrovna ukazkou dobreho navrhu a na objektovem programovani se mi mnohem vic libi jine vlastnosti (napr. zapouzdreni). Nicmene se obcas hodi i ta vicenasobna dedicnost. Interface je trochu o necem jinem a ma jine potize.

Vybiram si jazyky, podle toho, co lze. Ovsem kvuli potizim v C++, na ktere vede vas link uz do budoucna zadny jazyk nema mit vicenasobnou dedicnost? Co takhle odstranit prikaz goto (vim, ze N. Wirth uz pred lety posilal tento prikaz na propadliste dejin)? Neni to sice pekne, ale mnohdy je to pomoci goto (pripadne vice nez jedno return) progresivni - zvlast pokud mate rychle vyresit problem ciziho programu. Mimochodem zrusme goto, jsou programatori, kteri uz pomoci goto sve programy zabili v nekonecnych cyklech. Citim obrovsky rozdil mezi: 'neni to doporucovano' pred: 'jazyk to neumoznuje'. Mne rozhodnuti neumoznit vicenasobnou dedicnost prijde jako zhorsovak a ne zlepsovak. Vzdyt napriklad konfliktu jmen metod lze predejit, pokud se zavede princip, ze se metody vyhledavaji v poradi, v jakem byly objekty uvedeny pri deklaraci dedicnosti. Metody lze postupne hledat v prvnim rodicovskem objektu - nenalezneme - hledame postupne v dalsich. Pripadne se da prihlednou k pretizeni - vyhovuje nasi deklaraci - ne - tak hledame v jinem objektu. Konfliktu jmen atributu predejdeme, pokud se na atributy budeme divat jako na hash (pole, kde je indexem alfanum nazev). Predpokladam, ze kdyz se nekdo k mnohonasobne dedicnosti rozhodne, tak vi co dela.

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  19. 12. 2004 02:30

Jasně, v tomto smyslu nelze než souhlasit. Rovněž se osobně ztotožňuji s názorem, že čím více toho jazyk podporuje, tím lépe. Podpora vícenásobné dědičnosti má svou nezastupitelnou úlohu v určitých situacích. Chtěl jsem se jen zastat autora, který měl zřejmě na mysli známý fakt, že nejširší využití vícenásobné dědičnosti se v praxi uplatňuje právě pro tvorbu rozhraní knihoven a že pro tento účel jsou rozhraní jako jazykový prostředek vhodnější.

Já osobně jsem jsem vícenásobné dědičnosti nikdy nepotřeboval využít (protože jsem v rámci své profese dělal v Delphi a tam jsem si vystačil s rozhraními). Studiem knihy od autora C++ (Bjarne Stroustrup - Programovací jazyk C++) jsem došel k závěru, že vícenásobná dědičnost má nezastupitelnou úlohu, ale že zároveň musím být při jejím užití zvlášť obezřetný (zejména nemám-li patřičné zkušenosti). Nejsem si jist, zda Vámi navrhovaná řešení jsou nejvhodnější, ale opět souhlasím, že když se někdo k použití rozhodne, že by měl vědět, co dělá.

A "goto" v C# naštěstí zůstává

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  19. 12. 2004 09:46

 uz do budoucna zadny jazyk nema mit vicenasobnou dedicnost?
 
To jistě ne. Ačkoliv existují .NET jazyky, které vícenásobnou inheritanci podporují (např. Eiffel a v omezené míře Python)´, v CLS .NET pořadí deklarací na rozdíl od C++ nehraje roli a zavedení vícenásobné přímé dědičnosti do jazyka C# by vyžadovalo tuto kontrolu zavést na úrovni CLR, což by zkomplikovalo CodeDOM a implementaci MI ostatních jazyků, kde na pořadí nezáleží nemluvě o celé řadě dalších dopadů (viz např. diskusi zde http://blogs.gotdotnet.com/cbrumme/commentview.aspx/ec40acce-4ae4-44b8-93ce-27dd896b0d1d).
V jistém ohledu je omezující právě přímá násobná dědičnost, protože potomek od obou rodičů zdědí vše, co zdědit lze nespecifickým  stylem "všechno nebo nic" a nemám možnost toto chování potlačit, aniž bych příslušnou část rozhraní třídy učinili privátní a tím ji z inheritance jednou provždy vyloučili. Implementace třídy několika rozhraními současně naproti tomu umožňuje v každém ze vzorů vyčlenit pro dědění jen příslušnou část, implementující dané rozhraní, je to tedy v zásadě obecnější způsob - a pak je tedy věcí diskuse, zda implementovat i tu méně obecnější variantu, zvlášť když je spojena s praktickými i implementačními komplikacemi.
 
Co se debat nad tím, zda omezení specifikace konkrétního jazyka je výhoda nebo ne, lze jednoduše argumentovat tím, proč tedy ve všech jazycích nepovolit konstrukce, které se vyskytují i ve všech ostatních ("jakototgoto") a prakticky je tím sjednotit do jednoho monstrózního hybridu? Vidíte, že se dřív nebo později budete zřejmě muset v implementaci stejně někde zastavit a přijmout  rozhodnoutí, zda výhody obecnosti nepřeváží nad jednoduchostí použití. Že to není pro veřejnost abstraktní kritérium je vidět z toho, že jedna z věcí, které se C++ vyčítá je jeho přílišná "složitost".

Souhlasím  |  Nesouhlasím  |  Odpovědět
Arkobad  |  17. 12. 2004 16:48

Podarilo se mi z Japonska sehnat SDK k memu fotaku (Minolta DiMAGE Capture SDK for A2).
Je to v podstate jedine DLL obsahujici rozhrani k veskerym funkcim fotaku.
Kdyz jsem si toto DLL ale zkusil pridat do (referenci) projektu v C# i VB.NET, tak mi to reklo, ze smim pouzivat pouze DLLka kompatibilni s DotNETem, nebo prinejhorsim COMova DLLka (tedy ta s objektovym rozhranim). Dle manualu je alo toto DLL takove to klasicke, kde se funkce volaji klasicky podobne jako API funkce pres deklarace..
Je tedy mozne toto DLL ve VS.NET pouzivat, nebo se musim obratit na klasicke nastroje C++ ci VB6?

Souhlasím  |  Nesouhlasím  |  Odpovědět
Comm, Comm  |  17. 12. 2004 19:18

Asi ti nikdo neodpovi. Ano pro .NET musi byt DLL knihovna bud vytvorena v .NETu nebo musi obsahovat COM. Zrejme se budes opravdu obratit na Delphi/C++/VB 6.

Nekde jsem videl pripojeni i "klasicke" knihovny, ale moc dobre to nefungovalo. Mozna to bylo pripojena spatne (nestadartne) - nevim...

Souhlasím  |  Nesouhlasím  |  Odpovědět
pari  |  17. 12. 2004 21:22

Je potřeba použít Interop:

using System.Runtime.InteropServices; /* Required namespace for the DllImport method */

a potom nadefinovat hlavičku DLL, např:

[DllImport("HASPMS32.DLL", EntryPoint="hasp", CallingConvention = CallingConvention.StdCall)]
public static extern void hasp(
int service, int seed, int lptnum, int pass1, int pass2, ref int p1, ref int p2,
ref int p3, ref int p4 );

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  18. 12. 2004 13:10

Řada atributů té deklarace je ve skutečnosti implicitních a nemusí se používat. V prostředí VB.NET se z céčkové knihovny tatáž procedura naimportuje třeba takto:
 
Declare Sub hasp Lib "HASPMS32.DLL" (service%, seed%, lptNum%, pass1%, pass2%, ByRef p1%, ByRef p2%, ByRef p3%, ByRef p4%)
 
a v kódu použije následovně:
 
Dim p1% = 1, p2% = 2, p3% = 3, p4% = 4
hasp(1, 2, 3, 4, 5, p1, p2, p3, p4)
 
Volání funkcí importovaných z C, Pascal aj. knihoven se v prostředí .NET ve skutečnosti používá docela často, současně se tím však kontext změní na unmanaged, s příslušnými dopady na správu paměti a CAS. Proto pokud je to možné je vhodné dávat přednost podepsaným wrapperům a nativním funkcím .NET.

Souhlasím  |  Nesouhlasím  |  Odpovědět
morph  |  17. 12. 2004 16:06

super, konecne uci nekdo OOP programovani tak, jak se ma ucit, tzn. hned jde na objekty...

narozdil od serialu o vb.net se tady tento serial zive velice povedl - jen tak dal

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petrik  |  18. 12. 2004 14:48

Seriálů zabývajících se platformou .NET nikdy není dost a lze jen ocenit přístup redakce Živě, že se rozhodla financovat další. Myslím, že Petrův seriál o C# ten můj výborně doplňuje směrem k pokročilejšímu stylu programování. Na druhé straně můj kurs je o programování ve VB.NET, ne programování OOP. OOP je nedílná součást jazyka stejně, jako "klasické" programovací struktury, o které se opírají zkušenosti uživatelů starších verzí VB.

Souhlasím  |  Nesouhlasím  |  Odpovědět
morph  |  20. 12. 2004 21:02

nechci do Vas nejak burit, osobne si vsech lidi co pisi nejake clanky velice vazim, uz je proto, ze je to temer charitativni prace , ale ja neutocil na to ze neucite OOP(to neni jen Vas serial, ale prakticky kazdy druhy), ale spise bych vytknul Vasemu serialu, ze mi prijde jako Referencni prirucka, nez serial o prograamovani...

Souhlasím  |  Nesouhlasím  |  Odpovědět
viman  |  20. 12. 2004 22:10

Ou, ou...

Já mám pocit přesně opačný. VB.NET "vede" začátečníka krok za krokem programováním, nástroji a mnoha věcmi, které spolu souvisí. Se slovem "referenční" nemá vůbec nic společného. Tento seriál mi přijde mnohem "referenčnější" (i když vysvětluje i samotné OOP - opět ale příliš referenčně).

Autor VB.NET je podle mně mimořádně pečlivý.

Souhlasím  |  Nesouhlasím  |  Odpovědět
NA  |  17. 12. 2004 13:13

Myslím, že autor může trochu mást tím, v jakém kontextu používá slovo atribut. Přimlouval bych se z pohledu C# k používání slov jako "datový člen" nebo "vlastnost". Atribut má v jazyce C# i jiný význam.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Benjamin Hejda  |  17. 12. 2004 22:12

Atribut ma v C# jediny vyznam, a to ten, ktery jsi mel pravdepodobne na mysli ty. Pro "datove cleny" se v anglickem originalu oficialne pouziva field a do cestiny se to obvykle preklada jako field .

Souhlasím  |  Nesouhlasím  |  Odpovědět
Meescha  |  17. 12. 2004 08:58

Zajimavy serial, delam v C/C++ a doufam, ze zde neco pochytim i o C#, tak sned me pane Pus nezklamete Jedna pripominka, mohl jste definovat i programatora, kdyz volate konstruktor s parametrem, nekoho by to mohlo zmast...

Souhlasím  |  Nesouhlasím  |  Odpovědět
Pusak, Pusak  |  17. 12. 2004 20:47

Dobrý večer,
děkuji za upozornění, zdrojový kód pro třídu Programator tam měl být. Problém samozřejmě napravím.

S pozdravem Petr Puš

Souhlasím  |  Nesouhlasím  |  Odpovědět
Zasílat názory e-mailem: Zasílat názory Můj názor