I need to compare objects of different types which I know all have properties Id and Legacy_id. Unfortunately I cannot add interface to them since the types come from database schema. I hoped the following comparer would work:
type Comparer<'T >()=
interface System.Collections.Generic.IEqualityComparer<'T> with
member this.Equals (o1:'T,o2:'T)=
o1.Legacy_id=o2.Legacy_id
member this.GetHashCode(o:'T)=
o.Id+o.Legacy_id
Also I have instantiations of the comparer type with the types. So, theoretically compiler has enough information.
But it gives an error: "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved."
I wonder why F# fails here? Are there any real/theoretical restrictions or it is just not implemented? Such kind of inference could be very useful.
I suspect that an explanation is about F# compiler is only forward walking. The limitation C# doesn't have. That's what error message is complaining about. Is that so?
'Tis not guaranteed to have a property namedId. Here's a thought experiment: what would happen if you instantiated this class asComparer<int>? - Fyodor Soikin'Tdoes not have anIdproperty. C#/F# generics are typechecked once and are not expanded based on their usage like C++ templates. - LeeComparer<int>now, doesn't mean the compiler can know you won't do so in the future. Since it can't guarantee that, it can't assume that'Twill always have anIdproperty. - rmunn