CA2214: не вызывайте переопределяемые методы в конструкторах
TypeName |
DoNotCallOverridableMethodsInConstructors |
CheckId |
CA2214 |
Категория |
Microsoft.Usage |
Критическое изменение |
Не критическое |
Причина
Конструктор незапечатанного типа вызывает виртуальный метод, определенный в его классе.
Описание правила
При вызове виртуального метода фактический тип, выполняющий метод, не выбирается до времени выполнения. Когда конструктор вызывает виртуальный метод, возможна ситуация, когда конструктор для экземпляра, вызывающего метод, не выполняется.
Устранение нарушений
Чтобы устранить нарушение этого правила, не вызывайте виртуальные методы типа из конструкторов типа.
Отключение предупреждений
Для этого правила отключать вывод предупреждений не следует. Нужно переделать конструктор, устранив вызов виртуального метода.
Пример
В следующем примере показаны последствия нарушения этого правила. Тестовое приложение создает экземпляр DerivedType, вызывающий выполнение конструктора базового класса (BadlyConstructedType). Конструктор BadlyConstructedType неверно вызывает виртуальный метод DoSomething. Судя по выходным данным, DerivedType.DoSomething() выполняется, причем до выполнения конструктора 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
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();
}
}
}
После выполнения примера получается следующий результат.