Reputation: 3435
I have a problem with operator resolution on generic methods.
From my understanding of section 7.3.4 of the spec within the function EqualOperatorGeneric (sample code below) the correct overload of the == operator on the type A should be found, but instead it seems to get the candidate for (object, object).
Am I doing something very obvious wrong? Is there a method to get the expected behaviour and if not can I turn the given case into a compile time or runtime error?
public class A
{
public A(int num)
{
this.Value = num;
}
public int Value { get; private set; }
public override bool Equals(object obj)
{
var other = obj as A;
if (Object.ReferenceEquals(other, null))
return false;
return Object.Equals(this.Value, other.Value);
}
public override int GetHashCode()
{
return this.Value.GetHashCode();
}
public static bool operator ==(A l, A r)
{
if (Object.ReferenceEquals(l, null))
{
return !Object.ReferenceEquals(r, null);
}
return l.Equals(r);
}
public static bool operator !=(A l, A r)
{
return !(l == r);
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(EqualOperatorGeneric(new A(1), new A(1)));
}
public static bool EqualOperatorGeneric<L, R>(L l, R r)
where L : class
where R : class
{
return l == r;
}
}
Output:
False
Upvotes: 1
Views: 401
Reputation: 3435
After scrounging the spec I realized you can use the dynamic keyword to defer binding of the operator from compile time to runtime. This fixes the issues I have been having:
public static bool EqualOperatorGeneric<L, R>(L l, R r)
{
dynamic dl = l, dr = r;
return dl == dr;
}
Upvotes: 1
Reputation: 203820
When EqualOperatorGeneric
is compiled the ==
operator needs to be bound statically, when the method is compiled, to a single implementation. It is not bound separately for each separate usage of the generic method.
This is what differentiates generics from, say, C++ templates. The generic method is compiled once and then applied to every usage with every set of type arguments, whereas templates are compiled separately for each set of generic arguments.
Upvotes: 2