While coding some data handling classes I just answered my own
question.
Overload resolution works like this:
Which _method signature_ to call is resolved at compile time, based on
the type of the references / value types being passed as arguments.
Therefore, in my example, the compile will tell the run time to look
for a method called DoSomething that takes an argument of type "A",
because that is the type of the reference that was passed.
Polymorphism comes into play when you are invoking a method on an
_instance_. In other words, if you are calling method DoSomethingElse
that is an _instance method_ of A, and overridden in B, then the CLR
decides _at run time_ _which method to call_ based on the actual type
of the object on which the method is invoked. So,
A anA = new B();
A.DoSomethingElse(15);
will call B's "DoSomethingElse", not A's. So, putting it all together:
public class A
{
public virtual void DoSomethingElse(int arg) { ... }
public virtual void DoSomethingELse(double arg) { ... }
}
public class B : A
{
public override void DoSomethingElse(int arg) { ... }
public override void DoSomethingElse(double arg) { ... }
}
if you call
A myA = new B();
myA.DoSomethingElse((double)15);
the method invoked will be B's DoSomethingElse(double). The compiler
decides, at compile time, to invoke a DoSomethingElse that takes a
double parameter, based on the type passed as an argument. The CLR
decides, at run time, to invoke the DoSomethingElse(double) of B
because the object is really a B even though its reference is being
held in a variable of type A.
In the case of static methods, polymorphism doesn't come into play,
because there are no instances. So, everything about the call is
decided at compile time, based on the types of the arguments.
So, yes, saying
if ((object)string1 == (object)string2)
will, in fact, call Object's == operator. However, as I noted in
another post, this should do the same thing as string's == operator, so
I don't see the point.