Custom types and custom operations in OCL
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

We received this question:

I have an attribute of type TestStruct defined on a class.

TestStruct is defined as follows:

Code Snippet

public struct TestStruct : IComparable
{
public int Int1 { get; private set; }
public int Int2 { get; private set; }
public TestStruct(int int1, int int2)
: this()
{
this.Int1 = int1;
this.Int2 = int2;
}
public int CompareToX(object obj)
{
return CompareTo(obj);
}
public int CompareToX(TestStruct other)
{
return CompareTo(other);
}
public int CompareTo(TestStruct other)
{
return (Int1 + Int2).CompareTo(other.Int1 + other.Int2);
}

#region IComparable Members
public int CompareTo(object obj)
{
return CompareTo((TestStruct)obj);
}
#endregion
}

The following OCL expression gives an error: "Eco.FrameworkImpl.Ocl.EBoldOCLAbort: 31:Undefined operation: CompareTo"

Class1.allInstances.Attribute2.CompareTo(Class1.allInstances-

>first.Attribute2)

However, the expression:

Class1.allInstances.Attribute2.CompareToX(Class1.allInstances-

>first.Attribute2)

Works OK.

Why is this happening?

There are a couple of things that are interesting in this:

  1. ECO can use any native type you define as a type of an attribute (beware - you will need to explain how to persist the type if you want to store it in a database - AbstractSingleColumnAttribute, ISingleColumnAttributemapping, IDefaultReverseMapping)
  2. ECO will pick up on Methods of this native type and make them available in the Object constraint language – OCL – so that you can use the method in OCL and EAL.

How come CompareToX works, but CompareTo does not work?

Answer: CompareTo is common and well-known, so we hijack it and map it to the “=” operator of OCL. You need to do this:

Class1.allInstances.Attribute2=(Class1.allInstances->first.Attribute2)

While testing this, however, I was surprised that my CompareTo was still not called… It turned out that, in ECO, we used the Equals operator - you would need to amend your struct code with something like this: (GetHashCode override is to avoid the warning.)

public override bool Equals(Object obj)
{
return CompareTo(obj)==0;
}
public override int GetHashCode()
{
return Int1 ^ Int2;
}

It all seemed a bit complex in the end, so new builds of ECO have been changed to all look like this:

if (thisobject is IComparable)
  return ((IComparable)thisobject).CompareTo(elementAsObject)==0;
else
   return object.Equals(GetAsObject(), elementAsObject);

This, in turn, means that from now on, we will use IComparable, if implemented, for checking Equality on attribute types.

This page was edited 76 days ago on 02/10/2024. What links here