CA1501: Unikaj nadmiernego dziedziczenia

Właściwości Wartość
Identyfikator reguły CA1501
Tytuł Unikaj nadmiernego dziedziczenia
Kategoria Łatwość konserwacji
Poprawka powodująca niezgodność lub niezgodność Kluczowa
Domyślny próg 5
Domyślnie włączone na platformie .NET 8 Nie.

Przyczyna

Typ to pięć lub więcej poziomów głęboko w hierarchii dziedziczenia.

Opis reguły

Hierarchie typów głęboko zagnieżdżonych mogą być trudne do śledzenia, zrozumienia i utrzymania. Ta reguła ogranicza analizę do hierarchii w tym samym module.

Tę regułę można skonfigurować w następujący sposób:

  • Domyślnie reguła wyklucza typy z System przestrzeni nazw. Regułę można również skonfigurować tak, aby wykluczała inne typy lub przestrzenie nazw.
  • Możesz skonfigurować głębokość drzewa dziedziczenia, w której jest uruchamiana ta reguła.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, należy utworzyć typ z typu podstawowego, który jest mniej głęboki w hierarchii dziedziczenia lub wyeliminować niektóre typy bazowe pośrednie.

Kiedy pomijać ostrzeżenia

Można bezpiecznie pominąć ostrzeżenie z tej reguły. Jednak kod może być trudniejszy do utrzymania. W zależności od widoczności typów bazowych rozwiązywanie naruszeń tej reguły może spowodować powstanie zmian powodujących niezgodność. Na przykład usunięcie typów baz publicznych jest zmianą powodującą niezgodność.

Uwaga

Jeśli wszystkie następujące elementy mają zastosowanie, mogą pojawić się ostrzeżenia fałszywie dodatnie z tej reguły:

  • Używasz programu Visual Studio 2022 w wersji 17.5 lub nowszej ze starszą wersją zestawu .NET SDK, czyli platformą .NET 6 lub starszą.
  • Używasz analizatorów z zestawu .NET 6 SDK lub starszej wersji pakietów analizatora, takich jak Microsoft.CodeAnalysis.FxCopAnalyzers.

Wyniki fałszywie dodatnie są spowodowane zmianą powodującą niezgodność w kompilatorze języka C#. Rozważ użycie nowszego analizatora zawierającego poprawkę dla ostrzeżeń fałszywie dodatnich. Przeprowadź uaktualnienie do wersji Microsoft.CodeAnalysis.NetAnalyzers w wersji 7.0.0-preview1.22464.1 lub nowszej lub użyj analizatorów z zestawu .NET 7 SDK.

Pomijanie ostrzeżenia

Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.

#pragma warning disable CA1501
// The code that's violating the rule is on this line.
#pragma warning restore CA1501

Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none w pliku konfiguracji.

[*.{cs,vb}]
dotnet_diagnostic.CA1501.severity = none

Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.

Konfigurowanie progu

Można skonfigurować próg, przy którym jest uruchamiana ta reguła.

  1. Utwórz plik tekstowy o nazwie CodeMetricsConfig.txt.

  2. Dodaj żądany próg do pliku tekstowego w następującym formacie:

    CA1501: 8
    

    W tym przykładzie reguła jest skonfigurowana do uruchamiania, gdy typ ma osiem lub więcej poziomów głęboko w hierarchii dziedziczenia.

  3. W pliku projektu oznacz akcję kompilacji pliku konfiguracji jako AdditionalFiles. Na przykład:

    <ItemGroup>
      <AdditionalFiles Include="CodeMetricsConfig.txt" />
    </ItemGroup>
    

Konfigurowanie kodu do analizowania

Użyj następującej opcji, aby skonfigurować, które części bazy kodu mają być uruchamiane w tej regule.

Tę opcję można skonfigurować tylko dla tej reguły, dla wszystkich reguł, do których ma ona zastosowanie, lub dla wszystkich reguł w tej kategorii (możliwość konserwacji), których dotyczy. Aby uzyskać więcej informacji, zobacz Opcje konfiguracji reguły jakości kodu.

Dziedziczenie wykluczonych typów lub nazw przestrzeni nazw

Regułę można skonfigurować tak, aby wykluczyć niektóre typy lub przestrzenie nazw z drzewa hierarchii dziedziczenia. Domyślnie wszystkie typy z System.* przestrzeni nazw są wykluczone. Bez względu na to, jaka wartość jest ustawiona, ta wartość domyślna jest dodawana.

Wartość opcji Podsumowanie
dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = MyType Dopasuje wszystkie typy o nazwie MyType lub, których zawiera przestrzeń nazw MyType (i wszystkie typy z System przestrzeni nazw)
dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = MyType1|MyType2 Pasuje do wszystkich typów o nazwie MyType1 lub MyType2 lub, których zawierające przestrzeń nazw zawiera MyType1 lub MyType2 (i wszystkie typy z System przestrzeni nazw)
dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = T:NS.MyType Pasuje do określonego typu MyType w przestrzeni nazw NS (i wszystkich typów z System przestrzeni nazw)
dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = T:NS1.MyType1|T:NS2.MyType2 Pasuje do określonych typów MyType1 i MyType2 z odpowiednimi w pełni kwalifikowanymi nazwami (i wszystkimi typami z System przestrzeni nazw)
dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = N:NS Pasuje do wszystkich typów z NS przestrzeni nazw (i wszystkich typów z System przestrzeni nazw)
dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = My* Pasuje do wszystkich typów, których nazwa zaczyna się od lub której zawiera części przestrzeni nazw zaczyna się My od My (i wszystkich typów z System przestrzeni nazw)
dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = T:NS.My* Pasuje do wszystkich typów, których nazwa zaczyna się od My w przestrzeni nazw NS (i wszystkich typów z System przestrzeni nazw)
dotnet_code_quality.CA1501.additional_inheritance_excluded_symbol_names = N:My* Pasuje do wszystkich typów, których zawiera przestrzeń nazw zaczyna się od My (i wszystkich typów z System przestrzeni nazw)

Przykład

W poniższym przykładzie pokazano typ naruszający regułę:

class BaseClass {}
class FirstDerivedClass : BaseClass {}
class SecondDerivedClass : FirstDerivedClass {}
class ThirdDerivedClass : SecondDerivedClass {}
class FourthDerivedClass : ThirdDerivedClass {}

// This class violates the rule.
class FifthDerivedClass : FourthDerivedClass {}
Imports System

Namespace ca1501

    Class BaseClass
    End Class

    Class FirstDerivedClass
        Inherits BaseClass
    End Class

    Class SecondDerivedClass
        Inherits FirstDerivedClass
    End Class

    Class ThirdDerivedClass
        Inherits SecondDerivedClass
    End Class

    Class FourthDerivedClass
        Inherits ThirdDerivedClass
    End Class

    ' This class violates the rule.
    Class FifthDerivedClass
        Inherits FourthDerivedClass
    End Class

End Namespace