If you are using ECO with Delphi, then you might have wondered why all classes are in one huge file. To have every class in it’s own unit file, there is an option though. It seems though that there are quite some important reasons why this option is OFF by default.

I’ve read Blogs that actually recommend setting Tools – Options – ECO General Options – “one file per class” to ON.

My recommendation is though: leave it OFF. There are the following reasons to do so:

- It may make the code generator stumble in certain situations. See Holgers Blog on this.
I’m not sure if any of the mentioned problems have been addressed yet. Holger?

- All navigable associations / roles will be of type “System.Object”.
Let’s assume we have the following classes:

You would expect the following to work now:
 
  LCustomer := Customer.Create(EcoSpace);
  LCustomer.Name := ‘Olaf’;
  LOrder := Order.Create(EcoSpace);
  LOrder.Placed := DateTime.Now;
  LCustomer.Orders.Add(LOrder);
  //…
  LFirstOrderDate := LCustomer.Orders.Item[0].Placed;
  //…
  LCustomerName := LOrder.Customer.Name;

The lines marked in Blue, which are looking perfectly, won’t compile though (if “use one file per class” is set to ON). Why?

The reason is simple:
LOrder.Customer            TObject
LCustomer.Orders           IList
LCustomer.Orders.Item[0]   TObject

The types of the above expressions are all not of their expected types Customer, IOrderList and Order. They will return the red types instead. To work with these expressions you would have to type cast them to their expected types, which would work, but which is really ugly. Most important: you are losing type safety at design time. Mis-casted expressions will fail at run time, as the compiler can not detect your errors!

This is not an ECO bug though. If you have two classes in two units, each referencing the other one in it’s interface part, then you will end up with circular unit references. Usiing System.Object/TObject as “generic” type instead, is the only solution here.

Conclusion: Don’t use “On file per class” in Delphi (Pascal).
Note: C# works fine here, because there we don’t have that circular reference problem…

blog comments powered by Disqus
CodeGear Technology Partner