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 virtuali e 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 Dimensions 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 Dimensions e per ciascuna figura viene calcolata l'area della superficie. Ogni classe derivata ha la propria implementazione di override per Area(). Il programma calcola e visualizza l'area appropriata di ciascuna figura richiamando la corrispondente implementazione di Area() a seconda dell'oggetto associato al metodo.
Si noti che tutte le classi ereditate Circle, Sphere e Cylinder utilizzano costruttori che inizializzano la classe base. Ad esempio:
public Cylinder(double r, double h): base(r, h) {}
come avviene per l'elenco di inizializzazioni di C++.
class TestClass
{
public class Dimensions
{
public const double PI = Math.PI;
protected double x, y;
public Dimensions()
{
}
public Dimensions(double x, double y)
{
this.x = x;
this.y = y;
}
public virtual double Area()
{
return x * y;
}
}
public class Circle : Dimensions
{
public Circle(double r) : base(r, 0)
{
}
public override double Area()
{
return PI * x * x;
}
}
class Sphere : Dimensions
{
public Sphere(double r) : base(r, 0)
{
}
public override double Area()
{
return 4 * PI * x * x;
}
}
class Cylinder : Dimensions
{
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;
Dimensions c = new Circle(r);
Dimensions s = new Sphere(r);
Dimensions 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#)
Polimorfismo (Guida per programmatori C#)