Mixing data types in arithmetic OCL expressions
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 :-

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 :-
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 :-

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

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 :-

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

Software developer, family man, All Blacks fan, Playstation junkie, and headbanger since ages ago.
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