Polimorfismo.

El polimorfismo es una característica o funcionalidad más de la herencia. De hecho, la herencia implica el polimorfismo de las clases. Esto significa que toda clase derivada puede, implícitamente, convertirse en un objeto de su clase base. Tomemos como ejemplo estas dos clases:

public class BaseClass
{
    public int BaseProperty { get; set; }
}
public class InheritancedClass : BaseClass
{
    public int InheritancedProperty { get; set; }
}

Es posible declarar e instanciar un objeto del tipo 'InheritancedClass' y después asignarlo a un objeto de clase 'BaseClass':

InheritancedClass inheritancedClass = new InheritancedClass();
BaseClass baseClass = inheritancedClass;

Los miembros específicos de la clase derivada ya no están disponibles en el objeto de la clase base:

int i = baseClass.InheritancedProperty; // Error.

La conversión inversa, del tipo base al tipo derivado, se debe hacer de manera explícita:

inheritancedClass = (InheritancedClass)baseClass;

Aun así, si la conversión explícita fallara, dicha conversión se puede hacer mediante el operador 'as':

inheritancedClass = baseClass as InheritancedClass;

A continuación no está de más realizar una comprobación de si la conversión se ha realizado con éxito:

if (inheritancedClass != null)
{
    // La conversión se ha realizado con éxito.
}

Sin esta prueba la conversión sin el operador 'as' es más ventajosa, ya que el error que dará el compilador será más descriptivo.

int i = ((InheritancedClass)baseClass).InheritancedProperty;
int i = (baseClass as InheritancedClass).InheritancedProperty;

El operador 'is' permite probar el tipo de un objeto y, en consecuencia, predecir el resultado de una conversión:

InheritancedClass inheritancedClass = new InheritancedClass();
BaseClass baseClass = inheritancedClass;
if (baseClass is BaseClass) { } // Verdadero.
if (baseClass is InheritancedClass) { } // Verdadero.

Incluso si el objeto se convierte a su tipo base, la prueba con el operador 'is' refleja que el objeto está en el orgien del tipo derivado. Esto no es cierto en el caso de que el objeto se declare como un tipo base:

BaseClass baseClass2 = new BaseClass();
if (baseClass2 is BaseClass) { } // Verdadero.
if (baseClass2 is InheritancedClass) { } // Falso.

Por lo tanto, una referencia a una clase derivada puede ser convertica inmplícitamente por C# en una referencia a su clase base (directa o indirecta). Esto significa que es posible referirse a un objeto de una clase derivada utilizando una variable del tipo de su clase base.