No edit summary |
(Automatically adding template at the end of the page.) |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
We | We received this question:<blockquote>'''I have an attribute of type TestStruct defined on a class.'''</blockquote>TestStruct is defined as follows: | ||
'''Code Snippet''' | '''Code Snippet''' | ||
Line 32: | Line 32: | ||
<nowiki>#</nowiki>endregion | <nowiki>#</nowiki>endregion | ||
} | } | ||
The following | The following OCL expression gives an error: "Eco.FrameworkImpl.Ocl.EBoldOCLAbort: 31:Undefined operation: CompareTo"<blockquote>'''''Class1.allInstances.Attribute2.CompareTo(Class1.allInstances-'''''</blockquote><blockquote>'''''>first.Attribute2)'''''</blockquote>However, the expression:<blockquote>'''''Class1.allInstances.Attribute2.CompareToX(Class1.allInstances-'''''</blockquote><blockquote>'''''>first.Attribute2)'''''</blockquote>Works OK. | ||
'''''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? === | === Why is this happening? === | ||
There are a couple of things that are interesting in this: | |||
# 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) | # 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) | ||
# 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. | # 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:<blockquote>'''Class1.allInstances.Attribute2=(Class1.allInstances->first.Attribute2)'''</blockquote>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) | public override bool Equals(Object obj) | ||
{ | { | ||
Line 65: | Line 49: | ||
return Int1 ^ Int2; | return Int1 ^ Int2; | ||
} | } | ||
It all seemed a bit complex in the end so new builds of ECO | 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) | if (thisobject is IComparable) | ||
return ((IComparable)thisobject).CompareTo(elementAsObject)==0; | return ((IComparable)thisobject).CompareTo(elementAsObject)==0; | ||
else | else | ||
return object.Equals(GetAsObject(), elementAsObject); | 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. | |||
[[Category:OCL]] | [[Category:OCL]] | ||
{{Edited|July|12|2024}} |
Revision as of 15:29, 10 February 2024
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:
- 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)
- 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.