From b668edb9a609bcf912b49c33ccd00e9f46cc27d2 Mon Sep 17 00:00:00 2001 From: Christoph Hafner Date: Fri, 27 Sep 2024 15:02:12 +0200 Subject: [PATCH 1/4] Update ca1036.md Incorrect statement that VB.NET does not support operator overloading corrected and sample operators provided for C# and VB.NET --- .../code-analysis/quality-rules/ca1036.md | 227 +++++++++++++++++- 1 file changed, 221 insertions(+), 6 deletions(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1036.md b/docs/fundamentals/code-analysis/quality-rules/ca1036.md index 5114299764df8..e094c05eb5312 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca1036.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca1036.md @@ -40,18 +40,68 @@ To fix a violation of this rule, override . If you - op_LessThan - op_GreaterThan -In C#, the tokens that are used to represent these operators are as follows: +In C#, implement the following operators: ```csharp -== -!= -< -> + public static bool operator ==(SampleClass? one, SampleClass? other) { + throw new NotImplementedException(); + } + + public static bool operator !=(SampleClass? one, SampleClass? other) { + throw new NotImplementedException(); + } + + public static bool operator <(SampleClass? one, SampleClass? other) { + throw new NotImplementedException(); + } + + public static bool operator >(SampleClass? one, SampleClass? other) { + throw new NotImplementedException(); + } + + //Optionally also implement + + public static bool operator <=(SampleClass? one, SampleClass? other) { + throw new NotImplementedException(); + } + + public static bool operator >=(SampleClass? one, SampleClass? other) { + throw new NotImplementedException(); + } +``` + +In VB.NET, implement the following operators: +```vb + Public Shared Operator =(one As SampleClass, other As SampleClass) As Boolean + Throw New NotImplementedException() + End Operator + + Public Shared Operator <>(one As SampleClass, other As SampleClass) As Boolean + Throw New NotImplementedException() + End Operator + + Public Shared Operator <(one As SampleClass, other As SampleClass) As Boolean + Throw New NotImplementedException() + End Operator + + Public Shared Operator >(one As SampleClass, other As SampleClass) As Boolean + Throw New NotImplementedException() + End Operator + + 'Optionally also implement + + Public Shared Operator <=(one As SampleClass, other As SampleClass) As Boolean + Throw New NotImplementedException() + End Operator + + Public Shared Operator >=(one As SampleClass, other As SampleClass) As Boolean + Throw New NotImplementedException() + End Operator ``` ## When to suppress warnings -It is safe to suppress a warning from rule CA1036 when the violation is caused by missing operators and your programming language does not support operator overloading, as is the case with Visual Basic. If you determine that implementing the operators does not make sense in your app context, it's also safe to suppress a warning from this rule when it fires on equality operators other than op_Equality. However, you should always override op_Equality and the == operator if you override . +It is safe to suppress a warning from rule CA1036 when the violation is caused by missing operators and your programming language does not support operator overloading. If you determine that implementing the operators does not make sense in your app context, it's also safe to suppress a warning from this rule when it fires on equality operators other than op_Equality. However, you should always override op_Equality and the == operator if you override . ## Suppress a warning @@ -92,6 +142,171 @@ The following application code tests the behavior of the (one As SampleClass, other As SampleClass) As Boolean + If (one Is Nothing) Then Return (other IsNot Nothing) + If (other Is Nothing) Then Return True + Return (one.Value <> other.Value) + End Operator + + Public Shared Operator <(one As SampleClass, other As SampleClass) As Boolean + If (one Is Nothing) Then Return (other IsNot Nothing) + If (other Is Nothing) Then Return False + Return (one.Value < other.Value) + End Operator + + Public Shared Operator >(one As SampleClass, other As SampleClass) As Boolean + If (one Is Nothing) Then Return False + If (other Is Nothing) Then Return True + Return (one.Value > other.Value) + End Operator + + Public Shared Operator <=(one As SampleClass, other As SampleClass) As Boolean + If (one Is Nothing) Then Return True + If (other Is Nothing) Then Return False + Return (one.Value <= other.Value) + End Operator + + Public Shared Operator >=(one As SampleClass, other As SampleClass) As Boolean + If (one Is Nothing) Then Return (other Is Nothing) + If (other Is Nothing) Then Return True + Return (one.Value >= other.Value) + End Operator + +End Class +``` + +(Unit test of the example above) +```vb +Imports Microsoft.VisualStudio.TestTools.UnitTesting + + +Public Class UnitTest + + + Public Sub UseCase_A_eq_B() + Dim a As New SampleClass(42) + Dim b As New SampleClass(42) + Assert.AreEqual(0, a.CompareTo(b)) + Assert.IsTrue(a = b) + Assert.IsFalse(a <> b) + Assert.IsFalse(a < b) + Assert.IsFalse(a > b) + Assert.IsTrue(a <= b) + Assert.IsTrue(a >= b) + End Sub + + + Public Sub UseCase_A_lt_B() + Dim a As New SampleClass(42) + Dim b As New SampleClass(43) + Assert.AreEqual(-1, a.CompareTo(b)) + Assert.IsFalse(a = b) + Assert.IsTrue(a <> b) + Assert.IsTrue(a < b) + Assert.IsFalse(a > b) + Assert.IsTrue(a <= b) + Assert.IsFalse(a >= b) + End Sub + + + Public Sub UseCase_A_gt_B() + Dim a As New SampleClass(43) + Dim b As New SampleClass(42) + Assert.AreEqual(1, a.CompareTo(b)) + Assert.IsFalse(a = b) + Assert.IsTrue(a <> b) + Assert.IsFalse(a < b) + Assert.IsTrue(a > b) + Assert.IsFalse(a <= b) + Assert.IsTrue(a >= b) + End Sub + + + Public Sub UseCase_Nothing_NotNothing() + Dim a As SampleClass = Nothing + Dim b As New SampleClass(42) + Assert.IsFalse(a = b) + Assert.IsTrue(a <> b) + Assert.IsTrue(a < b) + Assert.IsFalse(a > b) + Assert.IsTrue(a <= b) + Assert.IsFalse(a >= b) + End Sub + + + Public Sub UseCase_NotNothing_Nothing() + Dim a As New SampleClass(42) + Dim b As SampleClass = Nothing + Assert.AreEqual(1, a.CompareTo(b)) + Assert.IsFalse(a = b) + Assert.IsTrue(a <> b) + Assert.IsFalse(a < b) + Assert.IsTrue(a > b) + Assert.IsFalse(a <= b) + Assert.IsTrue(a >= b) + End Sub + + + Public Sub UseCase_Nothing_Nothing() + Dim a As SampleClass = Nothing + Dim b As SampleClass = Nothing + Assert.IsTrue(a = b) + Assert.IsFalse(a <> b) + Assert.IsFalse(a < b) + Assert.IsFalse(a > b) + Assert.IsTrue(a <= b) + Assert.IsTrue(a >= b) + End Sub + + + Public Sub UseCase_A_Rogue() + Dim a As New SampleClass(42) + Dim rogue As String = "Something else" + Assert.AreEqual(0, a.CompareTo(rogue)) + End Sub + + + Public Sub UseCase_A_RogueNothing() + Dim a As New SampleClass(42) + Dim rogue As String = Nothing + Assert.AreEqual(1, a.CompareTo(rogue)) + End Sub + +End Class +``` +@Reviewer: End of snippets + ## See also - From 5ff2b8a461cfe1c69a873b69d233dec5b4124c3e Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Mon, 7 Oct 2024 12:19:42 -0700 Subject: [PATCH 2/4] put vb code into separate file --- .../code-analysis/quality-rules/ca1036.md | 235 ++---------------- .../snippets/csharp/all-rules/Program.cs | 1 + .../csharp/all-rules/all-rules.csproj | 8 + .../snippets/csharp/all-rules/ca1036.cs | 205 ++++++++------- .../snippets/vb/all-rules/Program.vb | 5 + .../snippets/vb/all-rules/all-rules.vbproj | 5 +- .../snippets/vb/all-rules/ca1036.vb | 99 ++++++++ ...able-types-with-serializableattribute_1.vb | 10 +- 8 files changed, 238 insertions(+), 330 deletions(-) create mode 100644 docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/Program.cs create mode 100644 docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/Program.vb create mode 100644 docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1036.vb diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1036.md b/docs/fundamentals/code-analysis/quality-rules/ca1036.md index e094c05eb5312..ac3f8abd378ca 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca1036.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca1036.md @@ -43,65 +43,35 @@ To fix a violation of this rule, override . If you In C#, implement the following operators: ```csharp - public static bool operator ==(SampleClass? one, SampleClass? other) { - throw new NotImplementedException(); - } - - public static bool operator !=(SampleClass? one, SampleClass? other) { - throw new NotImplementedException(); - } - - public static bool operator <(SampleClass? one, SampleClass? other) { - throw new NotImplementedException(); - } - - public static bool operator >(SampleClass? one, SampleClass? other) { - throw new NotImplementedException(); - } - - //Optionally also implement - - public static bool operator <=(SampleClass? one, SampleClass? other) { - throw new NotImplementedException(); - } - - public static bool operator >=(SampleClass? one, SampleClass? other) { - throw new NotImplementedException(); - } +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 VB.NET, implement the following operators: -```vb - Public Shared Operator =(one As SampleClass, other As SampleClass) As Boolean - Throw New NotImplementedException() - End Operator - - Public Shared Operator <>(one As SampleClass, other As SampleClass) As Boolean - Throw New NotImplementedException() - End Operator +In Visual Basic, implement the following operators: - Public Shared Operator <(one As SampleClass, other As SampleClass) As Boolean - Throw New NotImplementedException() - End Operator - - Public Shared Operator >(one As SampleClass, other As SampleClass) As Boolean - Throw New NotImplementedException() - End Operator +```vb +Public Shared Operator =(one As SampleClass, other As SampleClass) As Boolean + ... +End Operator - 'Optionally also implement +Public Shared Operator <>(one As SampleClass, other As SampleClass) As Boolean + ... +End Operator - Public Shared Operator <=(one As SampleClass, other As SampleClass) As Boolean - Throw New NotImplementedException() - 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 - Throw New NotImplementedException() - End Operator +Public Shared Operator >(one As SampleClass, other As SampleClass) As Boolean + ... +End Operator ``` ## When to suppress warnings -It is safe to suppress a warning from rule CA1036 when the violation is caused by missing operators and your programming language does not support operator overloading. If you determine that implementing the operators does not make sense in your app context, it's also safe to suppress a warning from this rule when it fires on equality operators other than op_Equality. However, you should always override op_Equality and the == operator if you override . +It's safe to suppress a warning from rule CA1036 when the violation is caused by missing operators and your programming language does not support operator overloading. If you determine that implementing the operators does not make sense in your app context, it's also safe to suppress a warning from this rule when it fires on equality operators other than `op_Equality`. However, you should always override `op_Equality` and the `==` operator if you override . ## Suppress a warning @@ -137,175 +107,12 @@ You can configure this option for just this rule, for all rules it applies to, o The following code contains a type that correctly implements . Code comments identify the methods that satisfy various rules that are related to and the interface. :::code language="csharp" source="snippets/csharp/all-rules/ca1036.cs" id="snippet1"::: +:::code language="vb" source="snippets/vb/all-rules/ca1036.vb" id="snippet1"::: The following application code tests the behavior of the implementation that was shown earlier. :::code language="csharp" source="snippets/csharp/all-rules/ca1036.cs" id="snippet2"::: - -@Reviewer: Please convert to snipped (I am editing this file in the browser and do not have the repo checked out, sorry) -(VB.NET example of a good implementation) -```vb -Public Class SampleClass - Implements IComparable - Implements IComparable(Of SampleClass) - - Public Sub New(value As Int32) - Me.Value = value - End Sub - - Public ReadOnly Property Value As Int32 - - Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo - If (obj Is Nothing) Then Return 1 - If (TypeOf obj IsNot SampleClass) Then Return 0 - Dim other As SampleClass = DirectCast(obj, SampleClass) - Return CompareTo(other) - End Function - - Public Function CompareTo(other As SampleClass) As Integer Implements IComparable(Of SampleClass).CompareTo - If (other Is Nothing) Then Return 1 - Return Comparer.DefaultInvariant.Compare(Value, other.Value) - End Function - - Public Shared Operator =(one As SampleClass, other As SampleClass) As Boolean - If (one Is Nothing) Then Return (other Is Nothing) - If (other Is Nothing) Then Return False - Return (one.Value = other.Value) - End Operator - - Public Shared Operator <>(one As SampleClass, other As SampleClass) As Boolean - If (one Is Nothing) Then Return (other IsNot Nothing) - If (other Is Nothing) Then Return True - Return (one.Value <> other.Value) - End Operator - - Public Shared Operator <(one As SampleClass, other As SampleClass) As Boolean - If (one Is Nothing) Then Return (other IsNot Nothing) - If (other Is Nothing) Then Return False - Return (one.Value < other.Value) - End Operator - - Public Shared Operator >(one As SampleClass, other As SampleClass) As Boolean - If (one Is Nothing) Then Return False - If (other Is Nothing) Then Return True - Return (one.Value > other.Value) - End Operator - - Public Shared Operator <=(one As SampleClass, other As SampleClass) As Boolean - If (one Is Nothing) Then Return True - If (other Is Nothing) Then Return False - Return (one.Value <= other.Value) - End Operator - - Public Shared Operator >=(one As SampleClass, other As SampleClass) As Boolean - If (one Is Nothing) Then Return (other Is Nothing) - If (other Is Nothing) Then Return True - Return (one.Value >= other.Value) - End Operator - -End Class -``` - -(Unit test of the example above) -```vb -Imports Microsoft.VisualStudio.TestTools.UnitTesting - - -Public Class UnitTest - - - Public Sub UseCase_A_eq_B() - Dim a As New SampleClass(42) - Dim b As New SampleClass(42) - Assert.AreEqual(0, a.CompareTo(b)) - Assert.IsTrue(a = b) - Assert.IsFalse(a <> b) - Assert.IsFalse(a < b) - Assert.IsFalse(a > b) - Assert.IsTrue(a <= b) - Assert.IsTrue(a >= b) - End Sub - - - Public Sub UseCase_A_lt_B() - Dim a As New SampleClass(42) - Dim b As New SampleClass(43) - Assert.AreEqual(-1, a.CompareTo(b)) - Assert.IsFalse(a = b) - Assert.IsTrue(a <> b) - Assert.IsTrue(a < b) - Assert.IsFalse(a > b) - Assert.IsTrue(a <= b) - Assert.IsFalse(a >= b) - End Sub - - - Public Sub UseCase_A_gt_B() - Dim a As New SampleClass(43) - Dim b As New SampleClass(42) - Assert.AreEqual(1, a.CompareTo(b)) - Assert.IsFalse(a = b) - Assert.IsTrue(a <> b) - Assert.IsFalse(a < b) - Assert.IsTrue(a > b) - Assert.IsFalse(a <= b) - Assert.IsTrue(a >= b) - End Sub - - - Public Sub UseCase_Nothing_NotNothing() - Dim a As SampleClass = Nothing - Dim b As New SampleClass(42) - Assert.IsFalse(a = b) - Assert.IsTrue(a <> b) - Assert.IsTrue(a < b) - Assert.IsFalse(a > b) - Assert.IsTrue(a <= b) - Assert.IsFalse(a >= b) - End Sub - - - Public Sub UseCase_NotNothing_Nothing() - Dim a As New SampleClass(42) - Dim b As SampleClass = Nothing - Assert.AreEqual(1, a.CompareTo(b)) - Assert.IsFalse(a = b) - Assert.IsTrue(a <> b) - Assert.IsFalse(a < b) - Assert.IsTrue(a > b) - Assert.IsFalse(a <= b) - Assert.IsTrue(a >= b) - End Sub - - - Public Sub UseCase_Nothing_Nothing() - Dim a As SampleClass = Nothing - Dim b As SampleClass = Nothing - Assert.IsTrue(a = b) - Assert.IsFalse(a <> b) - Assert.IsFalse(a < b) - Assert.IsFalse(a > b) - Assert.IsTrue(a <= b) - Assert.IsTrue(a >= b) - End Sub - - - Public Sub UseCase_A_Rogue() - Dim a As New SampleClass(42) - Dim rogue As String = "Something else" - Assert.AreEqual(0, a.CompareTo(rogue)) - End Sub - - - Public Sub UseCase_A_RogueNothing() - Dim a As New SampleClass(42) - Dim rogue As String = Nothing - Assert.AreEqual(1, a.CompareTo(rogue)) - End Sub - -End Class -``` -@Reviewer: End of snippets +:::code language="vb" source="snippets/vb/all-rules/ca1036.vb" id="snippet2"::: ## See also diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/Program.cs b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/Program.cs new file mode 100644 index 0000000000000..e221ad0970131 --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/Program.cs @@ -0,0 +1 @@ +TestCompare.Main1036("A", "B"); diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/all-rules.csproj b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/all-rules.csproj index 548868ecb5cdb..e39cd2fd94cd2 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/all-rules.csproj +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/all-rules.csproj @@ -7,6 +7,14 @@ all_rules + + 1701;1702;31049 + + + + 1701;1702;31049 + + diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca1036.cs b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca1036.cs index f00e506b471ce..a7443668d5edc 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca1036.cs +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca1036.cs @@ -1,143 +1,134 @@ using System; using System.Globalization; -namespace ca1036 +// +// 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 { - // - // 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 string Rating { get; private set; } - public class RatingInformation : IComparable, IComparable + public RatingInformation(string rating) { - public string Rating - { - get; - private set; - } + ArgumentNullException.ThrowIfNull(rating); - public RatingInformation(string 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) { - if (rating == null) - { - throw new ArgumentNullException("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.", "rating"); - } - - Rating = v; + throw new ArgumentException("Invalid rating value was specified.", nameof(rating)); } - 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.", "obj"); - } + Rating = v; + } - public int CompareTo(RatingInformation? other) + public int CompareTo(object? obj) + { + if (obj == null) { - if (other is null) - { - return 1; - } - - // Ratings compare opposite to normal string order, - // so reverse the value returned by String.CompareTo. - return -string.Compare(this.Rating, other.Rating, StringComparison.OrdinalIgnoreCase); + return 1; } - public static int Compare(RatingInformation left, RatingInformation right) + if (obj is RatingInformation other) { - if (object.ReferenceEquals(left, right)) - { - return 0; - } - if (left is null) - { - return -1; - } - return left.CompareTo(right); + return CompareTo(other); } - // Omitting Equals violates rule: OverrideMethodsOnComparableTypes. - public override bool Equals(object? obj) - { - if (obj is RatingInformation other) - { - return this.CompareTo(other) == 0; - } - - return false; - } + throw new ArgumentException("A RatingInformation object is required for comparison.", nameof(obj)); + } - // Omitting getHashCode violates rule: OverrideGetHashCodeOnOverridingEquals. - public override int GetHashCode() + public int CompareTo(RatingInformation? other) + { + if (other is null) { - char[] c = this.Rating.ToCharArray(); - return (int)c[0]; + return 1; } - // Omitting any of the following operator overloads - // violates rule: OverrideMethodsOnComparableTypes. - public static bool operator ==(RatingInformation left, RatingInformation right) + // 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)) { - if (left is null) - { - return right is null; - } - return left.Equals(right); + return 0; } - public static bool operator !=(RatingInformation left, RatingInformation right) + if (left is null) { - return !(left == right); + return -1; } - public static bool operator <(RatingInformation left, RatingInformation right) + return left.CompareTo(right); + } + + // Omitting Equals violates rule: OverrideMethodsOnComparableTypes. + public override bool Equals(object? obj) + { + if (obj is RatingInformation other) { - return (Compare(left, right) < 0); + return CompareTo(other) == 0; } - public static bool operator >(RatingInformation left, RatingInformation right) + + 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 (Compare(left, right) > 0); + 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); + } +} +// - // - public class Test +// +public class TestCompare +{ + public static void Main1036(params string[] args) { - public static void Main1036(string[] args) + if (args.Length < 2) { - if (args.Length < 2) - { - Console.WriteLine("usage - TestRatings string 1 string2"); - return; - } - RatingInformation r1 = new RatingInformation(args[0]); - RatingInformation r2 = new RatingInformation(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("{0} is {1} {2}", r1.Rating, answer, r2.Rating); + 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("{0} is {1} {2}", r1.Rating, answer, r2.Rating); } - // } +// diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/Program.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/Program.vb new file mode 100644 index 0000000000000..270931ba635c3 --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/Program.vb @@ -0,0 +1,5 @@ +Public Class Program + Public Shared Sub Main() + TestCompare.Main(New String() {"A", "B"}) + End Sub +End Class diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/all-rules.vbproj b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/all-rules.vbproj index 0f5343a149b29..7fc0bf3e28fad 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/all-rules.vbproj +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/all-rules.vbproj @@ -4,12 +4,9 @@ Exe all_rules net8.0 + $(NoWarn);BC30149 - - - - diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1036.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1036.vb new file mode 100644 index 0000000000000..67a19040854a6 --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1036.vb @@ -0,0 +1,99 @@ + +' +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 + + 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 + Return Comparer.DefaultInvariant.Compare(Rating, other.Rating) + 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 +' + +' +Public Class TestCompare + Public Shared Sub Main(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 +' diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2237-mark-iserializable-types-with-serializableattribute_1.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2237-mark-iserializable-types-with-serializableattribute_1.vb index f2b2bf5ba7f10..ce1c3dbff65fb 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2237-mark-iserializable-types-with-serializableattribute_1.vb +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2237-mark-iserializable-types-with-serializableattribute_1.vb @@ -1,6 +1,4 @@ -Imports System -Imports System.Runtime.Serialization -Imports System.Security.Permissions +Imports System.Runtime.Serialization Namespace ca2237 @@ -22,13 +20,15 @@ Namespace ca2237 End Sub Overridable Sub GetObjectData( - info As SerializationInfo, context As StreamingContext) _ - Implements ISerializable.GetObjectData + info As SerializationInfo, context As StreamingContext) info.AddValue("baseValue", baseValue) End Sub + Private Sub ISerializable_GetObjectData(info As SerializationInfo, context As StreamingContext) + Throw New NotImplementedException() + End Sub End Class End Namespace From f60aafad725a3ac98777983b5b51df5d1e26d505 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Mon, 7 Oct 2024 12:40:19 -0700 Subject: [PATCH 3/4] fix vb project --- .../snippets/csharp/all-rules/all-rules.csproj | 8 -------- .../quality-rules/snippets/vb/all-rules/Program.vb | 2 +- .../quality-rules/snippets/vb/all-rules/all-rules.vbproj | 2 +- .../ca1003-use-generic-event-handler-instances_1.vb | 2 +- .../quality-rules/snippets/vb/all-rules/ca1036.vb | 8 +++++--- ...rk-iserializable-types-with-serializableattribute_1.vb | 6 +----- 6 files changed, 9 insertions(+), 19 deletions(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/all-rules.csproj b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/all-rules.csproj index e39cd2fd94cd2..548868ecb5cdb 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/all-rules.csproj +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/all-rules.csproj @@ -7,14 +7,6 @@ all_rules - - 1701;1702;31049 - - - - 1701;1702;31049 - - diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/Program.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/Program.vb index 270931ba635c3..ce1cd9c2960e5 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/Program.vb +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/Program.vb @@ -1,5 +1,5 @@ Public Class Program Public Shared Sub Main() - TestCompare.Main(New String() {"A", "B"}) + TestCompare.Main1036(New String() {"C", "B"}) End Sub End Class diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/all-rules.vbproj b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/all-rules.vbproj index 7fc0bf3e28fad..a108957937cbd 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/all-rules.vbproj +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/all-rules.vbproj @@ -4,7 +4,7 @@ Exe all_rules net8.0 - $(NoWarn);BC30149 + $(NoWarn);SYSLIB0050 diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1003-use-generic-event-handler-instances_1.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1003-use-generic-event-handler-instances_1.vb index 4394e9d21e541..ea5fd681e4b24 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1003-use-generic-event-handler-instances_1.vb +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1003-use-generic-event-handler-instances_1.vb @@ -42,7 +42,7 @@ Namespace ca1003 Class Test - Shared Sub Main() + Shared Sub Main1003() Dim eventRaiser As New ClassThatRaisesEvent() Dim eventHandler As New ClassThatHandlesEvent(eventRaiser) diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1036.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1036.vb index 67a19040854a6..553bdf81e5e8d 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1036.vb +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca1036.vb @@ -16,7 +16,7 @@ Public Class RatingInformation Throw New ArgumentException("Invalid rating value was specified.", NameOf(rating)) End If - rating = v + Me.Rating = v End Sub Public ReadOnly Property Rating As String @@ -30,7 +30,9 @@ Public Class RatingInformation Public Function CompareTo(other As RatingInformation) As Integer Implements IComparable(Of RatingInformation).CompareTo If (other Is Nothing) Then Return 1 - Return Comparer.DefaultInvariant.Compare(Rating, other.Rating) + ' 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 @@ -77,7 +79,7 @@ End Class ' Public Class TestCompare - Public Shared Sub Main(ByVal args As String()) + Public Shared Sub Main1036(ByVal args As String()) If (args.Length < 2) Then Return End If diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2237-mark-iserializable-types-with-serializableattribute_1.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2237-mark-iserializable-types-with-serializableattribute_1.vb index ce1c3dbff65fb..c07faa5d2aa3c 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2237-mark-iserializable-types-with-serializableattribute_1.vb +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2237-mark-iserializable-types-with-serializableattribute_1.vb @@ -20,15 +20,11 @@ Namespace ca2237 End Sub Overridable Sub GetObjectData( - info As SerializationInfo, context As StreamingContext) + info As SerializationInfo, context As StreamingContext) Implements ISerializable.GetObjectData info.AddValue("baseValue", baseValue) End Sub - - Private Sub ISerializable_GetObjectData(info As SerializationInfo, context As StreamingContext) - Throw New NotImplementedException() - End Sub End Class End Namespace From d8406043130bba5ac91ce01a9c05525e04738b2c Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:32:46 -0700 Subject: [PATCH 4/4] fix dev_langs --- .../code-analysis/quality-rules/ca1036.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1036.md b/docs/fundamentals/code-analysis/quality-rules/ca1036.md index ac3f8abd378ca..b3c04be4de301 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca1036.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca1036.md @@ -10,6 +10,9 @@ helpviewer_keywords: - CA1036 author: gewarren ms.author: gewarren +dev_langs: +- CSharp +- VB --- # CA1036: Override methods on comparable types @@ -35,23 +38,22 @@ Types that define a custom sort order implement the in To fix a violation of this rule, override . If your programming language supports operator overloading, supply the following operators: -- op_Equality -- op_Inequality -- op_LessThan -- op_GreaterThan - -In C#, implement the following operators: +- `op_Equality` +- `op_Inequality` +- `op_LessThan` +- `op_GreaterThan` ```csharp +// 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 the following operators: - ```vb +' In Visual Basic, implement these operators. + Public Shared Operator =(one As SampleClass, other As SampleClass) As Boolean ... End Operator