I know I can avoid boxing by adding my own Equals implementation.
public struct TwoDoubles
{
public double m_Re;
public double m_Im;
public TwoDoubles(double one, double two)
{
m_Re = one;
m_Im = two;
}
public override bool Equals(object ob)
{
return Equals((TwoDoubles)ob);
}
public bool Equals(TwoDoubles ob)
{
TwoDoubles c = ob;
return m_Re == c.m_Re && m_Im == c.m_Im;
}
}
I can’t call this an override as much as an overload. By the magic of the runtime it does correctly call the correct Equals() implementation based on the type of the caller.
Why can’t I override and change the parameter type to TwoDoubles and let boxing occur by the power of the runtime on an as needed basis? Is it because C# doesn’t support parameter contravariance (if that’s the reason then why is it not supported…seems a small step from object o = new TwoDoubles())?
UPDATE
Clarification: object is a part of the inheritance hierarchy of a struct. Why can we not specify a more derived type as a parameter to override an implementation from a less derived type? This would allow us to write:
public override bool Equals(TwoDoubles ob)
{
TwoDoubles c = ob;
return m_Re == c.m_Re && m_Im == c.m_Im;
}
Which should be called when the variable is a TwoDouble even if said variable has been boxed into an object type.
Because that would not be typesafe!
And now you just passed a tiger to a method that actually only takes a giraffe!
Same thing in your case. You’re overriding a method that takes any object with a method that can only take a struct; that’s not typesafe.
No, it is because you are asking for parameter type covariance, which is not typesafe.
C# does not support parameter type contravariance either, but that’s not what you’re asking for.