Custom types and custom operations in OCL
(Created page with "We got this Question: TestStruct is defined as follows: '''Code Snippet''' public struct TestStruct : IComparable { public int Int1 { get; private set; } public int Int...")
 
No edit summary
Line 1: Line 1:
We got this Question:
We got this Question:<blockquote>'''I have an attribute of type TestStruct defined on a class.'''</blockquote>TestStruct is defined as follows:
 
TestStruct is defined as follows:


'''Code Snippet'''
'''Code Snippet'''

Revision as of 20:01, 22 October 2018

We got 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?

So 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.

So 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 go like this:

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

But while testing this I was surprised to find that my CompareTo was still not called… It turned out that we in ECO used the Equals operator, so you would need to amend your struct code with something like this: (GetHashCode override is to avoid 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 has been changed to call look like this:

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

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

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