CA2214: Non chiamare metodi sottoponibili a override nei costruttori
Proprietà | valore |
---|---|
ID regola | CA2214 |
Title | Non chiamare metodi sottoponibili a override nei costruttori |
Categoria | Utilizzo |
La correzione causa un'interruzione o meno | Non causa un'interruzione |
Abilitato per impostazione predefinita in .NET 9 | No |
Causa
Il costruttore di un tipo non bloccato chiama un metodo virtuale definito nella relativa 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 dai costruttori del tipo.
Quando eliminare gli avvisi
Non escludere 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
). BadlyConstructedType
Il costruttore di chiama erroneamente il metodo DoSomething
virtuale . Come illustrato nell'output, DerivedType.DoSomething()
viene eseguito prima DerivedType
dell'esecuzione del costruttore.
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 ? {0}", initialized);
}
}
public class TestBadlyConstructedType
{
public static void Main2214()
{
DerivedType derivedInstance = new DerivedType();
}
}
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.