Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
| Proprietà | valore |
|---|---|
| ID regola | CA2214 |
| Title | Non chiamare metodi sovrascrivibili nei costruttori |
| Categoria | Utilizzo |
| La correzione causa un'interruzione o meno | Non rompente |
| Abilitato per impostazione predefinita in .NET 10 | No |
| Linguaggi applicabili | C# e Visual Basic |
Causa
Il costruttore di un tipo non sigillato chiama un metodo virtuale definito nella propria classe.
Descrizione regola
Quando viene chiamato un metodo virtuale, il tipo effettivo che esegue il metodo non viene selezionato fino al runtime. Quando un costruttore chiama un metodo virtuale, è possibile che il costruttore per l'istanza che richiama il metodo non sia stato eseguito. Ciò potrebbe causare errori o comportamenti imprevisti, se un metodo virtuale sottoposto a override si basa sull'inizializzazione e su altre configurazioni nel costruttore.
Come correggere le violazioni
Per correggere una violazione di questa regola, non chiamare i metodi virtuali di un tipo all'interno dei costruttori del tipo.
Quando eliminare gli avvisi
Non sopprimere un avviso da questa regola. Il costruttore deve essere riprogettato per eliminare la chiamata al metodo virtuale.
Esempio
Nell'esempio seguente viene illustrato l'effetto della violazione di questa regola. L'applicazione di test crea un'istanza di DerivedType, che causa l'esecuzione del costruttore della classe di base (BadlyConstructedType).
BadlyConstructedTypeIl costruttore chiama in modo errato il metodo virtuale DoSomething. Come illustrato nell'output, DerivedType.DoSomething() viene eseguito prima che venga eseguito il costruttore di DerivedType.
public class BadlyConstructedType
{
protected string initialized = "No";
public BadlyConstructedType()
{
Console.WriteLine("Calling base ctor.");
// Violates rule: DoNotCallOverridableMethodsInConstructors.
DoSomething();
}
// This will be overridden in the derived type.
public virtual void DoSomething()
{
Console.WriteLine("Base DoSomething");
}
}
public class DerivedType : BadlyConstructedType
{
public DerivedType()
{
Console.WriteLine("Calling derived ctor.");
initialized = "Yes";
}
public override void DoSomething()
{
Console.WriteLine($"Derived DoSomething is called - initialized ? {initialized}");
}
}
public class TestBadlyConstructedType
{
public static void Main2214()
{
DerivedType derivedInstance = new();
}
}
Imports System
Namespace ca2214
Public Class BadlyConstructedType
Protected initialized As String = "No"
Public Sub New()
Console.WriteLine("Calling base ctor.")
' Violates rule: DoNotCallOverridableMethodsInConstructors.
DoSomething()
End Sub 'New
' This will be overridden in the derived type.
Public Overridable Sub DoSomething()
Console.WriteLine("Base DoSomething")
End Sub 'DoSomething
End Class 'BadlyConstructedType
Public Class DerivedType
Inherits BadlyConstructedType
Public Sub New()
Console.WriteLine("Calling derived ctor.")
initialized = "Yes"
End Sub 'New
Public Overrides Sub DoSomething()
Console.WriteLine("Derived DoSomething is called - initialized ? {0}", initialized)
End Sub 'DoSomething
End Class 'DerivedType
Public Class TestBadlyConstructedType
Public Shared Sub Main2214()
Dim derivedInstance As New DerivedType()
End Sub 'Main
End Class
End Namespace
Nell'esempio viene prodotto l'output seguente:
Calling base ctor.
Derived DoSomething is called - initialized ? No
Calling derived ctor.