Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Tulajdonság | Érték |
---|---|
Szabályazonosító | CA1036 |
Cím | Hasonló típusok felülbírálási módszerei |
Kategória | Tervezés |
A javítás vagy megszakítást okoz, vagy nem okoz | Nem törhető |
Alapértelmezés szerint engedélyezve a .NET 9-ben | Nem |
Ok
Egy típus implementálja az System.IComparable interfészt, és nem bírálja felül System.Object.Equals vagy nem túlterheli a nyelvspecifikus operátort az egyenlőség, az egyenlőtlenség, a kisebb vagy nagyobb érték miatt. A szabály nem jelent szabálysértést, ha a típus csak a felület implementációját örökli.
Ez a szabály alapértelmezés szerint csak külsőleg látható típusokat tekint meg, de ez konfigurálható.
Szabály leírása
Az egyéni rendezési sorrendet meghatározó típusok implementálják a IComparable felületet. A CompareTo metódus egy egész számot ad vissza, amely a megfelelő rendezési sorrendet jelzi a típus két példányához. Ez a szabály azonosítja azokat a típusokat, amelyek beállítják a rendezési sorrendet. A rendezési sorrend beállítása arra utal, hogy az egyenlőség, az egyenlőtlenség, a kisebb mint, és a nagyobb mint nem érvényesek. Amikor egy implementációt ad meg IComparable, általában felül kell bírálnia Equals is, hogy az azokat az értékeket adja vissza, amelyek összhangban vannak CompareTo-vel. Ha felülbírálja a Equals-t, és olyan nyelven kódol, amely támogatja az operátorok túlterhelését, akkor meg kell adnia olyan operátorokat is, amelyek összhangban vannak Equals-vel.
Szabálysértések kijavítása
A szabály megsértésének kijavításához írja felül a Equals. Ha a programozási nyelv támogatja az operátorok túlterhelését, adja meg a következő operátorokat:
op_Equality
op_Inequality
op_LessThan
op_GreaterThan
// In C#, implement these operators.
public static bool operator ==(SampleClass? one, SampleClass? other) { }
public static bool operator !=(SampleClass? one, SampleClass? other) { }
public static bool operator <(SampleClass? one, SampleClass? other) { }
public static bool operator >(SampleClass? one, SampleClass? other) { }
' In Visual Basic, implement these operators.
Public Shared Operator =(one As SampleClass, other As SampleClass) As Boolean
...
End Operator
Public Shared Operator <>(one As SampleClass, other As SampleClass) As Boolean
...
End Operator
Public Shared Operator <(one As SampleClass, other As SampleClass) As Boolean
...
End Operator
Public Shared Operator >(one As SampleClass, other As SampleClass) As Boolean
...
End Operator
Mikor kell letiltani a figyelmeztetéseket?
Nyugodtan letilthatja a CA1036 szabály figyelmeztetését, ha a szabály megsértését hiányzó operátorok okozzák, és a programozási nyelv nem támogatja az operátorok túlterhelését. Ha azt állapítja meg, hogy az operátorok megvalósítása nem értelmezhető az alkalmazáskörnyezetben, akkor nyugodtan el is tilthatja a szabály figyelmeztetését, ha nem egyenlőségi operátorokat op_Equality
aktivál. Mindazonáltal, ha felülbírálja Object.Equals, akkor mindig felül kell bírálnia op_Equality
és a ==
operátort is.
Figyelmeztetés mellőzése
Ha csak egyetlen szabálysértést szeretne letiltani, adjon hozzá előfeldolgozási irányelveket a forrásfájlhoz a szabály letiltásához és újbóli engedélyezéséhez.
#pragma warning disable CA1036
// The code that's violating the rule is on this line.
#pragma warning restore CA1036
Ha le szeretné tiltani egy fájl, mappa vagy projekt szabályát, állítsa annak súlyosságát none
a konfigurációs fájlban.
[*.{cs,vb}]
dotnet_diagnostic.CA1036.severity = none
További információ: Kódelemzési figyelmeztetések letiltása.
Elemzést végző kód konfigurálása
A következő beállítással konfigurálhatja, hogy a kódbázis mely részein futtassa ezt a szabályt.
Ezt a beállítást konfigurálhatja csak ehhez a szabályhoz, az összes szabályhoz, vagy az ebben a kategóriában (Tervezés) szereplő összes szabályhoz, amelyekre vonatkozik. További információ: Kódminőségi szabály konfigurációs beállításai.
Adott API-felületek belefoglalása
A api_surface beállítással konfigurálhatja, hogy a kódbázis mely részein futtassa a szabályt az akadálymentességük alapján. Ha például meg szeretné adni, hogy a szabály csak a nem nyilvános API-felületen fusson, adja hozzá a következő kulcs-érték párot a projekt egyik .editorconfig fájljához:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Jegyzet
Cserélje le a XXXX
CAXXXX
részét a vonatkozó szabály azonosítójára.
Példák
Az alábbi kód egy helyesen implementálható típust IComparabletartalmaz. A kód megjegyzései azonosítják azokat a metódusokat, amelyek megfelelnek a különböző szabályoknak, amelyek kapcsolódnak a Equals felülethezIComparable.
// Valid ratings are between A and C.
// A is the highest rating; it is greater than any other valid rating.
// C is the lowest rating; it is less than any other valid rating.
public class RatingInformation : IComparable, IComparable<RatingInformation>
{
public string Rating { get; private set; }
public RatingInformation(string rating)
{
ArgumentNullException.ThrowIfNull(rating);
string v = rating.ToUpper(CultureInfo.InvariantCulture);
if (v.Length != 1 ||
string.Compare(v, "C", StringComparison.Ordinal) > 0 ||
string.Compare(v, "A", StringComparison.Ordinal) < 0)
{
throw new ArgumentException("Invalid rating value was specified.", nameof(rating));
}
Rating = v;
}
public int CompareTo(object? obj)
{
if (obj == null)
{
return 1;
}
if (obj is RatingInformation other)
{
return CompareTo(other);
}
throw new ArgumentException("A RatingInformation object is required for comparison.", nameof(obj));
}
public int CompareTo(RatingInformation? other)
{
if (other is null)
{
return 1;
}
// Ratings compare opposite to normal string order,
// so reverse the value returned by String.CompareTo.
return -string.Compare(Rating, other.Rating, StringComparison.OrdinalIgnoreCase);
}
public static int Compare(RatingInformation left, RatingInformation right)
{
if (object.ReferenceEquals(left, right))
{
return 0;
}
if (left is null)
{
return -1;
}
return left.CompareTo(right);
}
// Omitting Equals violates rule: OverrideMethodsOnComparableTypes.
public override bool Equals(object? obj)
{
if (obj is RatingInformation other)
{
return CompareTo(other) == 0;
}
return false;
}
// Omitting getHashCode violates rule: OverrideGetHashCodeOnOverridingEquals.
public override int GetHashCode()
{
char[] c = Rating.ToCharArray();
return (int)c[0];
}
// Omitting any of the following operator overloads
// violates rule: OverrideMethodsOnComparableTypes.
public static bool operator ==(RatingInformation left, RatingInformation right)
{
if (left is null)
{
return right is null;
}
return left.Equals(right);
}
public static bool operator !=(RatingInformation left, RatingInformation right)
{
return !(left == right);
}
public static bool operator <(RatingInformation left, RatingInformation right)
{
return (Compare(left, right) < 0);
}
public static bool operator >(RatingInformation left, RatingInformation right)
{
return (Compare(left, right) > 0);
}
}
Imports System.Globalization
Public Class RatingInformation
Implements IComparable
Implements IComparable(Of RatingInformation)
Public Sub New(rating As String)
ArgumentNullException.ThrowIfNull(rating)
Dim v As String = rating.ToUpper(CultureInfo.InvariantCulture)
If (v.Length <> 1 Or
String.Compare(v, "C", StringComparison.Ordinal) > 0 Or
String.Compare(v, "A", StringComparison.Ordinal) < 0) Then
Throw New ArgumentException("Invalid rating value was specified.", NameOf(rating))
End If
Me.Rating = v
End Sub
Public ReadOnly Property Rating As String
Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
If (obj Is Nothing) Then Return 1
If (TypeOf obj IsNot RatingInformation) Then Return 0
Dim other As RatingInformation = DirectCast(obj, RatingInformation)
Return CompareTo(other)
End Function
Public Function CompareTo(other As RatingInformation) As Integer Implements IComparable(Of RatingInformation).CompareTo
If (other Is Nothing) Then Return 1
' Ratings compare opposite To normal String order,
' so reverse the value returned by String.CompareTo.
Return -String.Compare(Rating, other.Rating, StringComparison.OrdinalIgnoreCase)
End Function
Public Shared Operator =(one As RatingInformation, other As RatingInformation) As Boolean
If (one Is Nothing) Then Return (other Is Nothing)
If (other Is Nothing) Then Return False
Return (one.Rating = other.Rating)
End Operator
Public Shared Operator <>(one As RatingInformation, other As RatingInformation) As Boolean
If (one Is Nothing) Then Return (other IsNot Nothing)
If (other Is Nothing) Then Return True
Return (one.Rating <> other.Rating)
End Operator
Public Shared Operator <(one As RatingInformation, other As RatingInformation) As Boolean
If (one Is Nothing) Then Return (other IsNot Nothing)
If (other Is Nothing) Then Return False
Return (one.Rating < other.Rating)
End Operator
Public Shared Operator >(one As RatingInformation, other As RatingInformation) As Boolean
If (one Is Nothing) Then Return False
If (other Is Nothing) Then Return True
Return (one.Rating > other.Rating)
End Operator
Public Overrides Function Equals(obj As Object) As Boolean
If ReferenceEquals(Me, obj) Then
Return True
End If
If obj Is Nothing Then
Return False
End If
Throw New NotImplementedException()
End Function
Public Overrides Function GetHashCode() As Integer
Throw New NotImplementedException()
End Function
End Class
Az alábbi alkalmazáskód a korábban bemutatott implementáció viselkedését teszteli IComparable .
public class TestCompare
{
public static void Main1036(params string[] args)
{
if (args.Length < 2)
{
return;
}
RatingInformation r1 = new(args[0]);
RatingInformation r2 = new(args[1]);
string answer;
if (r1.CompareTo(r2) > 0)
answer = "greater than";
else if (r1.CompareTo(r2) < 0)
answer = "less than";
else
answer = "equal to";
Console.WriteLine($"{r1.Rating} is {answer} {r2.Rating}");
}
}
Public Class TestCompare
Public Shared Sub Main1036(ByVal args As String())
If (args.Length < 2) Then
Return
End If
Dim r1 As New RatingInformation(args(0))
Dim r2 As New RatingInformation(args(1))
Dim answer As String
If (r1.CompareTo(r2) > 0) Then
answer = "greater than"
ElseIf (r1.CompareTo(r2) < 0) Then
answer = "less than"
Else
answer = "equal to"
End If
Console.WriteLine("{0} is {1} {2}", r1.Rating, answer, r2.Rating)
End Sub
End Class