CA2214: Non chiamare metodi sottoponibili a override nei costruttori

Proprietà valore
ID regola CA2214
Titolo Non chiamare metodi sottoponibili a override nei costruttori
Categoria Utilizzo
Correzione che causa un'interruzione o un'interruzione Nessuna interruzione
Abilitato per impostazione predefinita in .NET 8 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). BadlyConstructedTypeIl costruttore di chiama erroneamente il metodo DoSomethingvirtuale . Come illustrato nell'output, DerivedType.DoSomething() viene eseguito prima DerivedTypedell'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.