Comparteix via


virtual (Referencia de C#)

Use la virtual palabra clave para modificar un método, una propiedad, un indexador o una declaración de eventos y permitir que una clase derivada lo invalide.

La documentación de referencia del lenguaje C# cubre la versión más reciente publicada del lenguaje C#. También contiene documentación inicial sobre las características de las versiones preliminares públicas de la próxima versión del lenguaje.

La documentación identifica cualquier característica introducida por primera vez en las últimas tres versiones del idioma o en las versiones preliminares públicas actuales.

Sugerencia

Para buscar cuándo se introdujo por primera vez una característica en C#, consulte el artículo sobre el historial de versiones del lenguaje C#.

Por ejemplo, cualquier clase que herede este método puede invalidarla:

public virtual double Area()
{
    return x * y;
}

Un miembro invalidado en una clase derivada puede cambiar la implementación de un miembro virtual. Para obtener más información sobre cómo usar la palabra clave virtual, vea Control de versiones con las palabras clave Override y New y Saber cuándo usar las palabras clave Override y New (Guía de programación de C#).

Cuando se invoca un método virtual, el tiempo de ejecución comprueba el tipo del objeto para un miembro invalidado. Llama al miembro que reemplaza en la clase más derivada. Si ninguna clase derivada invalida el miembro, se llama al miembro original.

De forma predeterminada, los métodos son no virtuales. No se puede invalidar un método no virtual.

En el siguiente ejemplo se muestra una propiedad virtual:

class MyBaseClass
{
    // virtual automatically implemented property. Overrides can only
    // provide specialized behavior if they implement get and set accessors.
    public virtual string Name { get; set; }

    // ordinary virtual property with backing field
    private int _num;
    public virtual int Number
    {
        get { return _num; }
        set { _num = value; }
    }
}

class MyDerivedClass : MyBaseClass
{
    private string _name;

    // Override automatically implemented property with ordinary property
    // to provide specialized accessor behavior.
    public override string Name
    {
        get
        {
            return _name;
        }
        set
        {
            if (!string.IsNullOrEmpty(value))
            {
                _name = value;
            }
            else
            {
                _name = "Unknown";
            }
        }
    }
}

Las propiedades virtuales se comportan como métodos virtuales, salvo por las diferencias en la sintaxis de declaración e invocación.

  • Una propiedad virtual heredada se puede invalidar en una clase derivada al incluir una declaración de propiedad que use el modificador override.

Ejemplo

En este ejemplo, la Shape clase contiene las dos coordenadas x y y, y el Area() método virtual. Las distintas clases de formas como Circle, Cylinder y Sphere heredan la clase Shape y se calcula el área de cada figura. Cada clase derivada tiene su propia implementación de invalidación de Area().

Las clases heredadas Circle, Cylindery Sphere todas usan constructores que inicializan la clase base, como se muestra en la siguiente declaración.

public Cylinder(double r, double h): base(r, h) {}

El programa siguiente calcula y muestra el área apropiada de cada figura al invocar a la implementación adecuada del método Area(), según el objeto asociado al método.

class TestClass
{
    public class Shape
    {
        public const double PI = Math.PI;
        protected double _x, _y;

        public Shape()
        {
        }

        public Shape(double x, double y)
        {
            _x = x;
            _y = y;
        }

        public virtual double Area()
        {
            return _x * _y;
        }
    }

    public class Circle : Shape
    {
        public Circle(double r) : base(r, 0)
        {
        }

        public override double Area()
        {
            return PI * _x * _x;
        }
    }

    public class Sphere : Shape
    {
        public Sphere(double r) : base(r, 0)
        {
        }

        public override double Area()
        {
            return 4 * PI * _x * _x;
        }
    }

    public class Cylinder : Shape
    {
        public Cylinder(double r, double h) : base(r, h)
        {
        }

        public override double Area()
        {
            return 2 * PI * _x * _x + 2 * PI * _x * _y;
        }
    }

    static void Main()
    {
        double r = 3.0, h = 5.0;
        Shape c = new Circle(r);
        Shape s = new Sphere(r);
        Shape l = new Cylinder(r, h);
        // Display results.
        Console.WriteLine($"Area of Circle   = {c.Area():F2}");
        Console.WriteLine($"Area of Sphere   = {s.Area():F2}");
        Console.WriteLine($"Area of Cylinder = {l.Area():F2}");
    }
}
/*
Output:
Area of Circle   = 28.27
Area of Sphere   = 113.10
Area of Cylinder = 150.80
*/

Especificación del lenguaje C#

Para obtener más información, consulte la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.

Vea también