virtual (Riferimenti per C#)

La parola chiave virtual viene utilizzata per modificare un metodo, una proprietà, un indicizzatore o una dichiarazione di evento e consente di sottoporli a override in una classe derivata.Ad esempio, è possibile effettuare l'override di questo metodo tramite qualsiasi classe che lo eredita:

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

In una classe derivata l'implementazione di un membro virtuale può essere modificata tramite override da un membro di una classe derivata.Per ulteriori informazioni sull'utilizzo della parola chiave virtual, vedere Controllo delle versioni con le parole chiave Override e New (Guida per programmatori C#) e Sapere quando utilizzare le parole chiave Override e New (Guida per programmatori C#).

Note

Quando si richiama un metodo virtuale, in fase di esecuzione viene verificata la presenza di un membro per l'esecuzione di override per il tipo dell'oggetto.Viene chiamato il membro per l'esecuzione di override nella classe derivata di livello più basso, che potrebbe coincidere con il membro originale nel caso in cui nessuna classe derivata abbia sottoposto il membro a override.

In base all'impostazione predefinita, i metodi sono non virtualie non possono essere sottoposti a override.

Non è possibile utilizzare il modificatore virtual insieme ai modificatori static, abstract, private o override.Nell'esempio seguente viene illustrata una proprietà virtuale:

class MyBaseClass
{
    // virtual auto-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 auto-implemented property with ordinary property
   // to provide specialized accessor behavior.
    public override string Name
    {
        get
        {
            return name;
        }
        set
        {
            if (value != String.Empty)
            {
                name = value;
            }
            else
            {
                name = "Unknown";
            }
        }
    }

}

Le proprietà virtuali hanno un comportamento analogo a quello dei metodi astratti, ma presentano delle differenze nella sintassi della dichiarazione e delle chiamate.

  • È errato utilizzare il modificatore virtual per una proprietà statica.

  • È possibile sottoporre a override una proprietà virtuale ereditata in una classe derivata includendo una dichiarazione di proprietà che utilizza il modificatore override.

Esempio

In questo esempio, la classe Shape contiene le due coordinate x e y e il metodo virtuale Area().Le diverse classi relative alle forme, come Circle, Cylinder e Sphere, ereditano la classe Shape e per ciascuna figura viene calcolata l'area della superficie.Ogni classe derivata ha la propria implementazione di override per Area().

Si noti che le classi ereditate Circle, Spheree Cylinder tutti i costruttori di utilizzo che consentono di inizializzare la classe base, come illustrato nella seguente dichiarazione.

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

Il seguente programma calcola e visualizza l'area appropriata per ogni figura richiamando l'implementazione appropriata di Area() metodo, a seconda dell'oggetto associato al metodo.

class TestClass
{
    public class Shape
    {
        public const double PI = Math.PI;
        protected double x, y;
        public Shape()
        {
        }
        public Shape(double x, double y)
        {
            this.x = x;
            this.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;
        }
    }

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

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

    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   = {0:F2}", c.Area());
        Console.WriteLine("Area of Sphere   = {0:F2}", s.Area());
        Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
        }
    }
    /*
        Output:
        Area of Circle   = 28.27
        Area of Sphere   = 113.10
        Area of Cylinder = 150.80
    */

Specifiche del linguaggio C#

Per ulteriori informazioni, vedere la Specifiche del linguaggio C#. La specifica del linguaggio è la fonte ufficiale per la sintassi e l'utilizzo di C#.

Vedere anche

Riferimenti

Modificatori (Riferimenti per C#)

Parole chiave di C#

Polimorfismo (Guida per programmatori C#)

abstract (Riferimenti per C#)

override (Riferimenti per C#)

new (Riferimenti per C#)

Concetti

Guida per programmatori C#

Altre risorse

Riferimenti per C#