CA2214 : N'appelez pas de méthodes substituables dans les constructeursCA2214: Do not call overridable methods in constructors

TypeNameTypeName DoNotCallOverridableMethodsInConstructorsDoNotCallOverridableMethodsInConstructors
CheckIdCheckId CA2214CA2214
CategoryCategory Microsoft.UsageMicrosoft.Usage
Modification avec ruptureBreaking Change Sans ruptureNon Breaking

CauseCause

Le constructeur d’un type unsealed appelle une méthode virtuelle définie dans sa classe.The constructor of an unsealed type calls a virtual method defined in its class.

Description de la règleRule description

Lorsqu’une méthode virtuelle est appelée, le type réel qui exécute la méthode n’est pas sélectionné jusqu'à l’exécution.When a virtual method is called, the actual type that executes the method is not selected until run time. Lorsqu’un constructeur appelle une méthode virtuelle, il est possible que le constructeur pour l’instance qui appelle la méthode n’a pas été exécutée.When a constructor calls a virtual method, it is possible that the constructor for the instance that invokes the method has not executed.

Comment corriger les violationsHow to fix violations

Pour corriger une violation de cette règle, n’appelez pas les méthodes virtuelles d’un type à partir de dans les constructeurs du type.To fix a violation of this rule, do not call a type's virtual methods from within the type's constructors.

Quand supprimer les avertissementsWhen to suppress warnings

Ne supprimez aucun avertissement de cette règle.Do not suppress a warning from this rule. Le constructeur doit être refondu pour éliminer l’appel à la méthode virtuelle.The constructor should be redesigned to eliminate the call to the virtual method.

ExempleExample

L’exemple suivant montre l’effet de violation de cette règle.The following example demonstrates the effect of violating this rule. L’application de test crée une instance de DerivedType, ce qui entraîne sa classe de base (BadlyConstructedType) constructeur à exécuter.The test application creates an instance of DerivedType, which causes its base class (BadlyConstructedType) constructor to execute. BadlyConstructedTypede manière incorrecte, le constructeur appelle la méthode virtuelle DoSomething.BadlyConstructedType's constructor incorrectly calls the virtual method DoSomething. Comme le montre la sortie, DerivedType.DoSomething() s’exécute et ce avant DerivedTypedu constructeur s’exécute.As the output shows, DerivedType.DoSomething() executes, and does so before DerivedType's constructor executes.

using System;

namespace UsageLibrary
{
    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 Main()
        {
            DerivedType derivedInstance = new DerivedType();
        }
    }
}

Imports System

Namespace UsageLibrary

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 Main()
        Dim derivedInstance As New DerivedType()
    End Sub 'Main
End Class 
End Namespace

Cet exemple génère la sortie suivante :This example produces the following output:

Calling base ctor.
Derived DoSomething is called - initialized ? No
Calling derived ctor.