Mixing data types in arithmetic OCL expressions

Posted by on in Blogs
I encountered a problem yesterday when attempting to perform arithmethic OCL operations on two attributes in my model which had different data types. One attribute is modeled as System.Double (TotalHours) and the other is modeled as System.Decimal (Rate). I needed to work out the total billable amount by multiplying the total hours worked by the rate per hour, and had expected that I could use the expression 'TotalHours * Rate' to create a derived attribute to express this calculation. However, this was met with the following error :-

TotalAmountBad

This is because that there is a difference in precision between the operands. In Delphi.NET you can perform operations using different data types, but as is also the case in C#, this is not allowed in OCL expressions.

It is possible to invoke CLR methods in the OCL editor, and as the System.Decimal data type exposes a .ToDouble method, it would be valid to change the OCL to 'TotalHours * Rate.ToDouble'. But doing so would result in a loss in precision, which is the whole reason for using the System.Decimal data type in the first place. And unfortunately the System.Decimal only has an explicit interface implementation of System.IConvertible.ToDecimal, and this cannot be invoked via OCL.

Thanks to Jonas Hogstrom, I was pointed to an easy solution to this problem. It is possible to register custom OCL operations which are resolved via reflection, and by decorating my EcoSpace class with the EcoOclOperation attribute, I could expose functionality in the System.Convert class, which could then be used in OCL expressions :-
uses
Eco.Ocl.Support,
...
type
[EcoSpace]
[EcoOclOperation(TypeOf(System.Convert), true)]
[EcoSpacePackage(TypeOf(ContractManagerClassesUnit.ContractManagerClasses))]
ContractManagerEcoSpace = class(Eco.Handles.DefaultEcoSpace)
...



After adding the above attribute and re-compiling, I now have both design-time and run-time access to the static methods of the System.Convert class, and can now convert the TotalHours attribute to System.Decimal with no loss of precision :-

TotalAmountGood

The EcoOclOperation attribute can also be used to register your own custom OCL operations, but in this case no wheel re-invention was needed.
Tags: .NET ECO


About
Gold User, Rank: 74, Points: 20
Software developer, family man, All Blacks fan, Playstation junkie, and headbanger since ages ago.

Comments

  • Guest
    Per Bakkendorff Monday, 24 September 2007

    Nice :) I was aware that you could just add an attribute to include design support for ocl operations. Do you know if they remembered to include support for more than one custom operation ?
    Per

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: