Navigation


German VFPConversion Developer's Blog

Dieser Blog ist allen VFP-Entwicklern gewidmet, die .NET und SQL Server in Ihren Applikationen einsetzen oder komplett darauf umsteigen wollen. Das inkludiert natuerlich auch .NET 3.0 Technologien wie WPF und WCF.

Content Area Footer

Monday, April 24, 2006
Ein Paradebeispiel für die Verwendung von Generics

Die .NET Runtime 2.0 hat ein sehr tolles neues Feature mit dem Namen „Generics“. Generics haben viel mit Strong-Typing zu tun. Wie Sie vielleicht wissen, sollte alles, was man in .NET macht, strong-typed sein, da dies einen positiven Effekt auf die Qualität und vieler anderer Dinge in Ihrer Applikation hat. Jedoch gibt es einige Anwendungsgebiete, bei denen Strong Typing unter .NET 1.1 ignoriert werden musste bzw. musste der Entwickler alternativ eine Unmenge an Code schreiben, um die Vorteile von Strong Typing auch in diesen Fällen nutzen zu können.

Ein Beispiel ist eine Liste von Objekten, die in einer Collection gespeichert warden. Hierfür bietet .NET verschiedene Klassen, wie beispielsweise die ArrayList-Klasse. Eine Array-List kann alle Objekt-Typen speichern. Beispielsweise kann eine Array-List aus Forms bestehen:

ArrayList myForms = new ArrayList();
myForms.Add(new Form());
myForms.Add(new Form());
myForms.Add(new CustomerEditForm());

Dies ist C#-Code. Hätten Sie eine ArrayList-Klasse in VFP entworfen, würde das so aussehen:

LOCAL myForms
myForms = CreateObject("ArrayList")
myForms.Add(CreateObject("Form"))
myForms.Add(CreateObject("Form"))
myForms.Add(CreateObject("CustomerEditForm"))

Eine Collection von Objekten kann in vielen Fällen sehr praktisch sein, zum Beispiel kann man alle Forms in einer Collection in einer Schleife abfragen und am Bildschirm anzeigen:

foreach (Form frm in myForms)
{
    frm.Show();
}

Es gibt jedoch ein Problem, wenn jemand in der Collection etwas anderes als eine Form speichert, denn eine ArrayList kann ja wiegesagt alle Arten von Objekten speichern, nicht nur Forms. Der folgende Code würde also zu einer Katastrophe führen:

ArrayList myForms = new ArrayList();
myForms.Add(new Form());
myForms.Add(new Form());
myForms.Add(new Button());
foreach (Form frm in myForms)
{
    frm.Show();
}

Dieser Code würde zur Laufzeit einen Fehler verursachen, denn es gibt keine Möglichkeit, die ArrayList dahingehend zu überprüfen, ob sich nur Forms in der Auflistung befinden. Wie kann man dieses Problem also in den Griff bekommen? In .NET 1.1 löst man diese Aufgabenstellung, indem man eine Subklasse aus der ArrayList erstellt und eine Vielzahl von Eigenschaften und Methoden ändert (beispielsweise kontrolliert man in der Add()-Methode, ob es sich beim hinzuzufügenden Objekt auch um eine Form handelt). Das größte Problem bei dieser Vorgangsweise ist der große Zeitaufwand: Man muss eine Subklasse für Forms entwerfen, eine andere für Buttons, eine weitere für DataSets usw. Bitte bedenken Sie, dass es tausende von verschiedenen Objekt-Typen im .NET-Framework gibt.

Aus diesem Grund wurde in .NET 2.0 das „Generics“-Feature eingeführt. Es ermöglicht Ihnen die generische Definition von Klassen (wie eine Klasse, die ähnlich der ArrayList-Klasse ist), aber wenn sie verwendet wird, kann man ihr einen spezifischen Zweck zuweisen. Im folgenden Beispiel sehen Sie die neue List Class, die wie eine generische ArrayList arbeitet:

List<Form> myForms = new List<Form>();
myForms.Add(new Form());
myForms.Add(new Form());
myForms.Add(new Button()); // Compiler Error!!!

In diesem Fall wird ein neues List-Objekt instanziiert, aber mit der Einschränkung, dass ausschließlich Forms in die Auflistung aufgenommen werden können. Der Objekt-Typ wird hierbei in Größer-Kleiner-Zeichen festgehalten. Anstatt zu sagen: „Wir instanziieren eine ArrayList“ würden wir jetzt „Wir instanziieren eine Liste mit Forms“ sagen.

Das ist ein hervorragendes Feature, denn es verbessert einerseits die Qualität des Codes und andererseits auch die Produktivität.

Ein weiteres Beispiel, wie man Generics außerhalb von Collections nutzen kann: Vor kurzer Zeit habe ich einem Kunden geholfen, seine Business Rules zu erstellen. Der Kunde verwendet unsere Milos Solution Platform (Framework) für die Erstellung seiner Applikationen, und Milos ermöglicht die Definition von Business Rules, als wären sie Klassen (wie die meisten Frameworks). Der Kunde wollte eine allgemeine Regel einrichten, die es ihm ermöglicht, jedes Datenfeld mit einem Wert zu vergleichen. Kein Wert sollte hierbei größer sein, als ein bestimmter Wert „X“.

In .NET 1.1 ist das durch sogenannte “IComparable”-Objekte möglich. Viele Objekte, wie auch Integers, Decimals, Strings usw., führen IComparable aus. Damit ist es möglich, „if (x > 0)" abzufragen, womit X mit 0 verglichen wird und true zurückgib, wenn X größer als 0 ist. Es ist auch möglich, ‚if ("B" > "A")' abzufragen, was true zurückgib, weil A vor dem B im Alphabet vorkommt. Dies funktioniert mit jedem Objekt, das IComparable benützt. Daher kann die folgende Methode verwendet werden (C#):

public class MyRule
    public bool
IsGreater(IComparable val1, IComparable val2)
    {
        if (val1.CompareTo(val2) > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

Diese Methode kann nun mit 2 Parametern (Integers / Numbers) aufgerufen warden, da Integers IComporable unterstützen. Der folgende Syntax ist also gültig:

MyRule x = new MyRule();
x.IsGreater(10,5);

Der folgende Syntax ist ebenso gültig, da Strings auch IComparable unterstützen:

MyRule x = new MyRule();
x.IsGreater("Athens","Rome");

So weit so gut. Der Knackpunkt ist jedoch, dass beide Parameter nicht nur IComparable unterstützen müssen, sondern vor allem auch vom selben Typ sein müssen. In anderen Worten: Auch, wenn beide Parameter IComparable unterstützen, würde der folgende Syntax nicht funktionieren:

MyRule x = new MyRule();
x.IsGreater(10,"Rome");

Und genau das kann sehr verwirrend sein. Ein typisches Fehlerszenario tritt auf, wenn zwei verschiedene numerische Parameter übergeben werden (beispielsweise decimal und integer). Wir brauchen also eine Möglichkeit, diese zwei Parameter generisch zu übergeben, aber wenn die Methode verwendet wird, müssen beide Parameter zu einem bestimmten Typ „konvertiert“ werden. Und dies ist der Fall, wenn die selbe Methode mit Hilfe der Generics erstellt wirdAnd this can be a bummer, because sometimes this gets confusing. A typical failure scenario would be one where two different numeric types (decimal and integer for instance) are passed. What we need is a way to implement this as generically as demonstrated here, but when the method is used, it needs to be restricted to a specific type. And once again, this can be done when the same method is implemented through generics:

MyRule<int> x = new MyRule<int>();
x.IsGreater(10,20);
x.IsGreater(10,"Rome"); // Compiler Error!!!

Aus meiner Sicht ist das ein sehr brauchbares Anwendungsgebiet von Generics. Es schützt uns vor hunderten von Fehlern, weil wir Strong-Type-Regeln umgehen wollen oder müssen, und unser Code wird beim Kompilieren bereits auf mögliche Fehler geprüft.

Zwischendurch: vor einiger Zeit hat Markus Egger über die Erstellung eines Length-Datentypen (Englisch) gebloggt. Damals haben eine Leser Diskussionen angefangen, ob es wirklich Vorteile bringt, einen neuen Datentyp zu entwickeln, oder ob bestehende Methoden und Objekte aus VFP nicht für denselben Zweck ausreichend sind. Das folgende Business Roule-Beispiel zeigt die Vorteile von eigenen Datentypen auf. Der Length-Datentyp, den er in diesem Beispiel verwendet, kann in der Business Rule-Klasse wie folgt verwendet werden:

MyRule<Length> x = new MyRule<Length>();
x.IsGreater(new Length("5 foot 6 inch"),new Length("1m 25cm"));

Es gibt somit keinen Unterschied zwischen der Verwendung eines eigenen Datentyps und den wesentlichen, bestehenden Datentypen, solange beide Datentypen IComporable unterstützen.

Wenn Sie an weiteren Informationen über Generics interessiert sind, folgen Sie diesem Link aus dem Code:

http://www.code-magazine.com/SearchResults.aspx?search=Generics 



Posted @ 9:26 AM by Jaros, Gerhard (gerhard@eps-software.com) -
Comments (13)


Wednesday, April 12, 2006
LINQ

LINQ stehr fuer "Language Integrated Query" und ist ein neues Feature dass Entwicklern in .NET 3.0 ("Orcas") zur Verfuegung steht. Als FoxPro Programmierer kann man sich LINQ aehnlich der FoxPro DML (Data Manipulation Language) vorstellen. Also z.B. SELECT Befehle, die direkt in .NET Sprachen wie C# oder VB.NET unterstuetzt werden. Einer der grossen Unterschiede ist dass es in .NET keine Unterscheidung zwischen Daten und Objekten gibt. Das hat den Vorteil dass LINQ nicht nur SELECT Befehle ueber Daten absetzen kann, sondern auch auf beliebige Objekte. Z.B. ist es moeglich alle leeren Textboxen auf einem Formular zu selektieren. Es ist auch moeglich SELECTs direkt auf XML Dokumente anzuwenden, usw.

Ich habe unlaengst einen Artikel zu diesem Thema im CoDe Magazine veroeffentlicht. Der Artikel kann sowohl auf der CoDe Magazine Seite, sowie auch hier auf VFPConversion.de online gelesen werden:

Kuerzere Artikel zum selben Thema finden sich auch auf VFPConversion.de unter folgenden Links:

Ein interessanter Externer Artikel befasst sich mit dem XML Support in LINQ (auch bekannt als "XLINQ"):

LINQ ist eine ueberaus interessante Technologie die vor allem FoxPro Programmierern gefallen duerfte. Es ist relativ offensichtlich das viele der FoxPro Ideen in LINQ eingeflossen sind und es sich praktisch um eine Fortfuehrung einer FoxPro Tradition in .NET handelt...

 



Posted @ 8:52 PM by Egger, Markus (markus@code-magazine.com) -
Comments (13)


Thursday, April 06, 2006
Die ersten Workshops sind vorbei...

Die ersten deutschprachigen VFPConversion.de Workshops sind vorbei, und wir freuen uns mitteilen zu koennen dass sie durchwegs als Erfolg einzustufen sind. Man moege es uns hier nachsehen dass wir hier "ins eigene Horn blasen", aber das Feedback der Teilnehmer war durchwegs sehr positiv. Hier einige Beispiele:

Am ersten Tag sehr viele Infos, insbesondere die in VFP nicht/kaum geläufigen OOP-Konzepte Interfaces, Delegates etc. fanden viele interessant.
Allerdings auch verwirrend, aber alle schienen trotzdem zufrieden, weil klar war, dass man mehr Zeit brauchen würde, um die einzelnen Themen zu vertiefen.
Der mehr Praxis orientierte zweite Tag erfüllte voll die Erwartungen.

Ich hab niemanden getroffen, der gesagt hätte, dass die Teilnahme sich nicht gelohnt hätte.
Viele hatten Lust auf mehr.
Alle waren mit Kompetenz und Unterhaltungswert der Redner sehr zufrieden.

In den Newsgroups wurde folgende Message gepostet:

So, gestern abend bin ich mit rauchendem Kopf wieder nach Hause gefahren.:-) Ich möchte mich an dieser Stelle noch mal bei allen beteiligten Leuten von Prolib und EPS bedanken!!! Das war ein prima organisierter Workshop.
Inhaltlich spitze. Bestimmt aber wären zwei Wochen statt zwei Tage besser gewesen ;-)

Direkt per Email ist folgende Nachricht bei uns eingegangen:

Ich möchte mich für den wirklich gelungenen Workshop in Kassel bedanken! Ich habe jetzt nach dem Workshop noch Kontakt zu ein paar Kollegen. Die Aussagen die ich überall höre reichen von „Das ist ja gar nicht so schlimm!“ bis „Ab 2007 mache ich neue Anwendungen nur noch mit DotNet.“

Auch mir geht es da im Prinzip nicht anders. Ich werde VFP auf jeden Fall weiter machen und auch mit VFX zusammen, welches ja wirklich viel Arbeit abnimmt – und damit meine ich nicht die Builder. Aber für neue Sachen möchte ich, gerade wenn es ein WEB-Interface geben soll und Daten auf Oracel oder SQL-Server gehalten werden sollen, durchaus VS benutzen.

Und mal so nebenbei: Was haben wir „VFPler“ eigentlich mit der Datenanbindung für Probleme? Wenn ich in VFP mit Views und CA’s arbeite und meine Daten auf einem SQL-Server habe, ist es doch das selbe in „grün“.

Auch per Email kam folgendes:

Hiermit möchte ich mich nochmals für die sehr informative und professionelle Veranstaltung in Kassel bedanken.

In DotNet entwickeln? Diese Frage hat sich für mich, als eingefleischter Foxpro Entwickler, eigentlich nicht gestellt, denn es gibt ja nichts besseres als Foxpro ;-). Nach dieser Vorstellung bin ich jedoch überzeugt. Mein Fazit: Um die aktuellen Techniken in Zukunft nutzen zu können, geht kein Weg an .Net vorbei, deshalb müssen wir frühzeitig die Weichen in die richtige Richtung stellen und dazu wird es jetzt schon "höchste Eisenbahn". Deshalb wäre ich auch an einer Vertiefung der .Net Kenntnisse interessiert.

Die Workshops scheinen also recht gut angekommen zu sein. Ueber derartiges Feedback freuen wir uns natuerlich sehr.

Es ist auch des oefteren die Frage nach zusaetzlichen Workshops aufgekommen. Zum einen haben wir hier natuerlich vor weitere aehnliche Workshops anzubieten. Der naechste (in Zuerich) ist ja bereits geplant. (Und nebenbei erwaehnt: auch in Nordamerika geht's weiter mit einem Workshop in Montreal). Des weiteren sind wir gerade dabei uns z beraten ob ein fortgeschrittener Workshop ueber mehrere Tage sinnvoll waere. Zu diesem Thema wuerden wir uns ueber Meinungen freuen.

Zusaetzlich gibt's natuerlich immer die Moeglichkeit eine Individualschulung zu diesem Thema bei uns zu buchen...

Mehr Informationen zu allgemeinen Schulungen, sowie Individualschulungen und andere Konvertierungsfragen und -aufgaben gibt's natuerlich auf www.VFPConversion.de.

 

Posted @ 8:37 PM by Egger, Markus (markus@code-magazine.com) -
Comments (10)


 

 

 

 

 

 

 

Syndication RSS 2.0 RSS 2.0

All My Blogs:
My personal blogs:
Dev and Publishing Dev and Publishing
Travel and Internat. Living Travel and Internat. Living
Other blogs I contribute to:
Milos Blog (US) Milos Blog (US)
VFPConv. Dev Blog (US) VFPConv. Dev Blog (US)
VFPConv. Dev Blog (DE) VFPConv. Dev Blog (DE)

 

Blog Archives
All Blog Posts

2007
    August (1)
    July (1)
    June (2)
    January (1)
2006
    December (1)
    November (2)
    October (1)
    August (1)
    April (3)
    March (3)

 

 

 

This Blog is powered by MilosTM Collaboration Components.