다음을 통해 공유


CA2214: 재정의 가능한 메서드를 생성자에서 호출하지 마십시오.

속성
규칙 ID CA2214
제목 재정의 가능한 메서드를 생성자에서 호출하지 마십시오.
범주 사용 현황
수정 사항이 주요 변경인지 여부 주요 변경 아님
.NET 9에서 기본적으로 사용 아니요

원인

봉인되지 않은 형식의 생성자는 해당 클래스에 정의된 가상 메서드를 호출합니다.

규칙 설명

가상 메서드가 호출되면 메서드를 실행하는 실제 형식이 런타임까지 선택되지 않습니다. 생성자가 가상 메서드를 호출할 때 해당 메서드를 호출하는 인스턴스의 생성자가 실행되지 않았을 수 있습니다. 재정의된 가상 메서드가 생성자의 초기화 및 기타 구성에 의존하는 경우 오류 또는 예기치 않은 동작이 발생할 수 있습니다.

위반 문제를 해결하는 방법

이 규칙 위반 문제를 해결하려면 형식의 생성자 내에서 형식의 가상 메서드를 호출하지 마세요.

경고를 표시하지 않는 경우

이 규칙에서는 경고를 표시해야 합니다. 가상 메서드에 대한 호출을 제거하려면 생성자를 다시 디자인해야 합니다.

예시

다음 예제에서는 이 규칙을 위반했을 때의 영향을 보여 줍니다. 테스트 애플리케이션은 기본 클래스(BadlyConstructedType) 생성자를 실행하는 DerivedType 인스턴스를 만듭니다. BadlyConstructedType의 생성자가 가상 메서드 DoSomething을 잘못 호출합니다. 출력에 표시된 것처럼 DerivedType.DoSomething()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 ? {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

이 예제는 다음과 같은 출력을 생성합니다.

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