VFPConversion Blog

This blog is dedicate to the adoption of technologies such as Microsoft .NET or SQL Server in addition to Visual FoxPro. Expect posts on this blog to be fairly technical, as this blog is geared towards developers, testers, and technical decision makers.

Content Area Footer

Saturday, April 22, 2006
A Nice Use of Generics

The .NET Runtime 2.0 has a very nice new feature called "Generics". Generics have a lot to do with strong-typing. As you probably know, everything one does in .NET is supposed to be strongly types, since it has such a positive impact on code quality (among other things). However, there are some areas where strong typing had to be violated in .NET up to version 1.1, or - as an alternative - the developer had to do an insane amount of work to get the advantages of strong typing.

One example are lists of objects stored in collections. For this purpose, .NET offers various classes, such as the ArrayList class. An array list can store any object type. For instance, an array list can store form classes:

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

This is C# code. If there was an ArrayList class in VFP (or if you created one yourself), it would be used in this fashion:

LOCAL myForms
myForms = CreateObject("ArrayList")

Having collections of objects is very useful in many ways. For instance, we can now iterate over these forms to show them all on screen:

foreach (Form frm in myForms)

Now here is the problem: What if someone stored something other than a Form instance into that collection? An ArrayList can store any object, not just forms. So this would be a disaster:

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

This would fail at runtime, since there is no way for the ArrayList class to control that only a certain type of object can be stored in that particular instance.

So how can we solve this problem? In .NET 1.1, this problem is solved by subclassing the ArrayList class and changing a number of members (such as the Add() method) to accept only Form classes. The problem with this is that it is very time consuming to do this. One has to create a subclass for forms, another for buttons, another for DataSets, and so on. (Keep in mind that there are thousands of different object types in the .NET Framework).

This is why .NET 2.0 introduces a the "Generics" feature. It allows for the generic definition of classes (such as an ArrayList-like class), but then when it is used, define a more specific purpose. This example shows the new List class, which is a generics-enabled version of the ArrayList:

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

In this case, a new List object is instantiated, but it is stated that in this instance, only Form objects can be stored in it. This is defined in the angle brackets. Instead of saying "we instantiate an ArrayList", we would now say "we instantiate a List of Form".

This is very cool, because is is great for code quality as well as productivity.

Now here is a very cool example for the use of generics in a non-collection example: I recently helped a customer to create business rules. The customer uses our Milos Solution Platform (framework) to create their application, and Milos (like many other frameworks) allows for the definition of business rules as classes (this is only one of the ways of doing this... but exact workings of Milos are not the subject of this post). The customer wanted to create a generic rule that allowed them to compare any data field to a value and say "this is only valid of the value is greater than X".

In .NET 1.1, this sort of rule could be implemented through objects that "implement IComparable". Many objects, such as integers, decimals, strings,... implement IComparable. This way, it is possible to say "if (x > 0)", which compares x to 0 and evaluates to true if x is indeed greater than 0. It also allows us to say 'if ("B" > "A")', which evaluates to true, since A is before B in the alphabet. So this works with every object that implements IComparable. Therefore, a method that compares to values could be implemented like this in C#:

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

We can now call this method passing two integers (numbers), since integers implement IComparable. So the following is perfectly valid:

MyRule x = new MyRule();

The following is also valid, since strings implement IComparable:

MyRule x = new MyRule();

So far so good. The only gotcha here is that both passed parameters need to be not just of a type that implements IComparable, but they in fact need to be the SAME type. In other words: This would not work despite both parameters being IComparable:

MyRule x = new MyRule();

And 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,"Rome"); // Compiler Error!!!

I thought this was a very nice use of Generics. It saved us from having to create potentially hundreds of different strongly-typed rules and still get full compiler quality checking.

BTW: A little while back I blogged about the creation of a Length data type. At the time, some readers discussed whether there was a real advantage over creating a new data type, or whether the same advantages could be achieved through methods and objects implemented in VFP. This business rule example is a good demonstration of why it is advantageous to have custom types. The Length type I created in this example can be used with this same business rule class like so:

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

There is no difference between the usage of this custom type and the intrinsic types. As long as the custom type implements IComparable, it will work in all the scenarios all the other types work.

BTW: If you are interested in more info about generics, check out the following CoDe Magazine search link:


Posted @ 6:06 PM by Egger, Markus ( -

Wednesday, April 12, 2006

LINQ stands for "Language Integrated Query" and is a new feature that will be available in .NET 3.0 ("Orcas"). FoxPro developers can envision LINQ very similar to the FoxPro DML (Data Manipulation Language). Think "SELECT commands in C#/VB.NET" and you are right on the money. Of course, one of the big differences between .NET and VFP is that .NET does not differentiate between data and objects. This means that in LINQ, SELECT commands run against all kinds of sources, including lists of objects and XML documents. (And of course regular data).

I recently had an article about LINQ in CoDe Magazine. The article can be read online at the CoDe Magazine site as well as on

There also are a few shorter articles on LINQ on this site:

Another interesting article that discusses LINQ's XML support (also known as "XLINQ") can be found at this URL:

LINQ is a very interesting technology, especially for VFP developers. After all LINQ introduces features that remove many of the .NET pain points for VFP developers. Looking at LINQ, it is obvious that much of the VFP spirit went into LINQ. Some even say this could be considered to be VFP 10. I am not sure that I would go quite that far, although those people do have a point...

Posted @ 9:00 PM by Egger, Markus ( -

Thursday, April 06, 2006
Europe's first set of VFPConversion Workshops

We just went through our first set of European VFPConversion Workshops in Germany and Austria. We were not really sure what to expect, since some people especially in Germany were relatively set on using VFP in the future. To our surprise and delight, we received a warm welcome there, and people were genuinely happy with the workshops we delivered. We may be tooting our own horn here, but we received the following feedback (translated), so we think people liked what they saw:

The first day had tons of info, especially about OOP concepts that are strange to VFP developers such as interfaces, delegates, and so forth. Everyone I talked to found these topics to be very interesting. Some a little confusing perhaps, but interesting nevertheless. It was clear that some concepts would take a while to sink in.
Also, the second day, which was very practice-oriented entirely fulfilled expectations.

I have not met anyone who thought that it wasn't worth attending.
Most were motivated to see more.
Everyone was happy with the competence and entertainment value of all the speakers.

In the german newsgroups, someone posted the following message:

When I went home after the workshop yesterday, my head was about to explode. :-)  I would like to say thanks to everyone involved in organizing the workshop (ProLib and EPS). The event was very well organized.
The content was top! The only thing that would have been better is for the workshop to last 2 weeks instead of 2 days ;-)

We received the following message via email:

I would like to thank everyone for a very well done workshop in Kassel! After the workshop I had the opportunity to talk to some colleges. All of them seem to agree that "this isn't as bad as I thought!" and "starting in 2007, I want to do all my new development exclusively with DotNet.".

I have to agree. I feel the same way. I will continue to use VFP and VFX, which saves a lot work (not just due to the builders). But for new things, especially if it involves a web interface, and if the data is to be stored in SQL Server or Oracle, I will use Visual Studio.

And as a side-remark: Why are we VFP developers so negative about data access in .NET? If I use VFP with Views and CAs and my data is stored in SQL Server, then I am facing practically the same scenario [as in .NET].

Also per email:

I would like to thank you for a very informative and professional workshop in Kassel!

"Should I develop in .NET?". As a die-hard VFP developer, I have never even asked myself this question before. After all, there isn't anything better than Visual FoxPro ;-). But after attending this workshop, I am convinced! My conclusion: To use up-to-date technologies in the future, one has to use .NET. For this reason, it is important to start using .NET sooner rather than later. And as far as I am concerned, it is "5 minutes to twelve" and I want to start right away, before it is too late. In fact, I would even appreciate an additional, in-depth workshop as a followup event.

So it seems people liked the events. It of course is always good to get such feedback! We are now also thinking about doing more workshops in Europe (one for Zurich, Switzerland is already planned) and of course also in North America (Montreal is next in combination with DevTeach). We are also thinking about more advanced workshops (more than 2 days each). If you think that is a good idea, send us some feedback! And of course, you always have the option of calling us in for a personalized training session or other VFPConversion related services. For more information, check our In particular, the training and events page.

Posted @ 9:37 PM by Egger, Markus ( -








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

    February (1)
    November (1)
    October (2)
    April (1)
    March (1)
    August (1)
    July (1)
    June (2)
    March (1)
    January (1)
    December (1)
    November (2)
    October (1)
    September (1)
    August (1)
    April (3)
    March (2)
    February (1)
    January (1)
    December (2)
    November (3)
    October (2)
    September (7)
    August (3)
    July (4)
    June (12)




This Blog is powered by MilosTM Collaboration Components.