Delen via


CA2214: Geen overschrijfbare methoden in constructors aanroepen

Eigenschap Waarde
Regel-id CA2214
Titel Overschrijfbare methoden in constructors niet aanroepen
Categorie Gebruik
Reparatie is een brekende of niet-brekende Niet-brekend
Standaard ingeschakeld in .NET 10 Nee

Oorzaak

De constructor van een niet-afgesloten type roept een virtuele methode aan die is gedefinieerd in de klasse.

Beschrijving van regel

Wanneer een virtuele methode wordt aangeroepen, wordt pas tijdens de uitvoeringstijd het werkelijke type geselecteerd dat de methode uitvoert. Wanneer een constructor een virtuele methode aanroept, is het mogelijk dat de constructor van het exemplaar dat de methode aanroept nog niet is uitgevoerd. Dit kan leiden tot fouten of onverwacht gedrag, als een overschreven virtuele methode afhankelijk is van initialisatie en andere configuratie in de constructor.

Hoe schendingen te verhelpen

Als u een schending van deze regel wilt oplossen, roept u de virtuele methoden van een type niet aan vanuit de constructors van het type.

Wanneer waarschuwingen onderdrukken

Een waarschuwing van deze regel niet onderdrukken. De constructor moet opnieuw worden ontworpen om de aanroep naar de virtuele methode te elimineren.

Voorbeeld

In het volgende voorbeeld ziet u het effect van het schenden van deze regel. De testtoepassing maakt een exemplaar van DerivedType, waardoor de basisklasseconstructor (BadlyConstructedType) wordt uitgevoerd. BadlyConstructedTypeDe constructor roept de virtuele methode DoSomethingonjuist aan. Zoals in de uitvoer wordt weergegeven, wordt DerivedType.DoSomething() uitgevoerd voordat de constructor van DerivedType wordt uitgevoerd.

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

In dit voorbeeld wordt de volgende uitvoer gegenereerd:

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