This code fails, f1 and f2 are not considered to be equal:
var gdb = await Geodatabase.OpenAsync(@"mytest.geodatabase");
var ft = gdb.GeodatabaseFeatureTables.First();
var f1 = (await ft.QueryFeaturesAsync(new QueryParameters {WhereClause = "OBJECTID=1"})).Single();
var f2 = (await ft.QueryFeaturesAsync(new QueryParameters {WhereClause = "OBJECTID=1"})).Single();
Assert.AreEqual(f1, f2);
I really wonder, if this is intended behavior or not.
I'd say, it's really good that we are not getting the same object here, this helps avoiding memory leaks a lot. But shouldn't two objects of the same type with the same properties be considered equal?
Solved! Go to Solution.
This is intended. Every time you pull a row out of a table, it's converted into a feature object. Thus the reference would never be equal. The behavior matches what you see with any other database queries in .NET (and most if not all other platforms where the data storage isn't in-memory)
This is intended. Every time you pull a row out of a table, it's converted into a feature object. Thus the reference would never be equal. The behavior matches what you see with any other database queries in .NET (and most if not all other platforms where the data storage isn't in-memory)
You would have to implement your own IEqualityComparer to define what "Equal" means in this case. Your Assert would then need to be .IsTrue(A.Equals(B, MyComparer).
internal class FeatureComparer : IEqualityComparer<Feature>
{
public bool Equals(Feature x, Feature y)
{
try
{
if ( x == null ) return false;
if ( y == null ) return false;
Field xField = x.FeatureTable.Fields.First(f => f.FieldType == FieldType.GlobalID);
Field yField = y.FeatureTable.Fields.First(f => f.FieldType == FieldType.GlobalID);
return x.GetAttributeValue(xField).Equals(y.GetAttributeValue(yField));
}
catch
{
return false;
}
}
public int GetHashCode(Feature obj)
{
return obj.GetHashCode();
}
}
Wow, that got fast responses 🙂
@Morten: I didn't know, other database queries in .NET behave the same. Thanks for sharing background information along with your answer!
@Joe: Thanks for your suggestion. I think, in case of an own comparer, the GetHashCode method should be implemented based on the same values as well. At least, that's the case if anyone decides to override Equals within the object itself.
That would probably be the better approach. But I had no intention of using as a Dictionary/Hash key so took the lazy approach.