From a1bdaf78840b13f09cb148335180c9276f04beac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Oct 2025 18:07:58 +0000 Subject: [PATCH 1/4] Initial plan From eeb68b72ba0b6bcaaeaa5ce7613a0680acf92d92 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Oct 2025 18:15:42 +0000 Subject: [PATCH 2/4] Document CA2208 paramName requirement and add examples Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- .../code-analysis/quality-rules/ca2208.md | 20 ++++++- .../snippets/csharp/all-rules/ca2208.cs | 52 +++++++++++++++++++ ...antiate-argument-exceptions-correctly_1.vb | 44 ++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca2208.md b/docs/fundamentals/code-analysis/quality-rules/ca2208.md index 01a18c7671706..750d5706a6eeb 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca2208.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca2208.md @@ -1,7 +1,7 @@ --- title: "CA2208: Instantiate argument exceptions correctly (code analysis)" description: "Learn about code analysis rule CA2208: Instantiate argument exceptions correctly" -ms.date: 05/18/2020 +ms.date: 10/24/2025 f1_keywords: - CA2208 - InstantiateArgumentExceptionsCorrectly @@ -31,6 +31,7 @@ When a method has a parameter, and it throws an exception type that is, or deriv - A call is made to the default (parameterless) constructor of an exception type that is, or derives from, that also has a constructor that accepts a `paramName` parameter. - An incorrect string argument is passed to a parameterized constructor of an exception type that is, or derives from, . - One of the parameters' names is passed for the `message` argument of the constructor of exception type that is, or derives from, . +- The `paramName` argument doesn't match the name of one of the method's parameters. ## Rule description @@ -47,6 +48,9 @@ The signatures of the one and two string constructors of ) - [`DuplicateWaitObjectException(string parameterName, string message)`]() +> [!IMPORTANT] +> The `paramName` argument passed to or its derived types must match the name of one of the method's parameters. If the null or invalid value isn't from the method's input arguments, use a different exception type. For example, use when an object's state is invalid. + ## How to fix violations To fix a violation of this rule, call a constructor that takes a message, a parameter name, or both, and make sure the arguments are proper for the type of being called. @@ -109,6 +113,20 @@ The following code fixes the previous violation by switching the constructor arg :::code language="vb" source="snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb" id="snippet2"::: +### Example - paramName doesn't match a method parameter + +The following code shows a method that incorrectly throws with a `paramName` that doesn't match any of the method's parameters. The rule fires because `bar` is a local variable, not a method parameter. + +:::code language="csharp" source="snippets/csharp/all-rules/ca2208.cs" id="snippet3"::: + +:::code language="vb" source="snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb" id="snippet3"::: + +The following code fixes the previous violation by using instead, which is appropriate when an object's state is invalid. + +:::code language="csharp" source="snippets/csharp/all-rules/ca2208.cs" id="snippet4"::: + +:::code language="vb" source="snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb" id="snippet4"::: + ## Related rules - [CA1507: Use nameof in place of string](ca1507.md) diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2208.cs b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2208.cs index ee6ec8b8972b9..13db7ff354f6f 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2208.cs +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2208.cs @@ -33,3 +33,55 @@ public Book(string title) } // } + +namespace ca2208_3 +{ +#pragma warning disable CA2208 // Instantiate argument exceptions correctly + // + public class Foo + { + public string? Bar { get; set; } + public string Name { get; set; } = string.Empty; + } + + public class Example + { + // Violates CA2208: 'bar' is not a parameter of this method. + public void ProcessFoo(Foo foo) + { + string? bar = foo.Bar; + if (bar is null) + { + throw new ArgumentNullException(nameof(bar), $"Foo named {foo.Name} had no Bar!"); + } + // Process bar... + } + } + // +#pragma warning restore CA2208 // Instantiate argument exceptions correctly +} + +namespace ca2208_4 +{ + // + public class Foo + { + public string? Bar { get; set; } + public string Name { get; set; } = string.Empty; + } + + public class Example + { + // Fixed: Use InvalidOperationException for invalid object state. + public void ProcessFoo(Foo foo) + { + string? bar = foo.Bar; + if (bar is null) + { + throw new InvalidOperationException($"Foo named {foo.Name} had no Bar!"); + } + // Process bar... + } + } + // +} diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb index 5a30b39595c9d..07fda84d30d36 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb @@ -51,3 +51,47 @@ Namespace ca2208_2 ' End Namespace + +Namespace ca2208_3 +#Disable Warning CA2208 ' Instantiate argument exceptions correctly + ' + Public Class Foo + Public Property Bar As String + Public Property Name As String = String.Empty + End Class + + Public Class Example + ' Violates CA2208: 'bar' is not a parameter of this method. + Public Sub ProcessFoo(ByVal foo As Foo) + Dim bar As String = foo.Bar + If bar Is Nothing Then + Throw New ArgumentNullException(NameOf(bar), $"Foo named {foo.Name} had no Bar!") + End If + ' Process bar... + End Sub + End Class + ' +#Enable Warning CA2208 ' Instantiate argument exceptions correctly + +End Namespace + +Namespace ca2208_4 + ' + Public Class Foo + Public Property Bar As String + Public Property Name As String = String.Empty + End Class + + Public Class Example + ' Fixed: Use InvalidOperationException for invalid object state. + Public Sub ProcessFoo(ByVal foo As Foo) + Dim bar As String = foo.Bar + If bar Is Nothing Then + Throw New InvalidOperationException($"Foo named {foo.Name} had no Bar!") + End If + ' Process bar... + End Sub + End Class + ' + +End Namespace From a2a7f573b4c196b22af0e1183d7c2e3977e6d0a1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Oct 2025 23:14:19 +0000 Subject: [PATCH 3/4] Replace Foo/Bar with Product/Description in CA2208 examples Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- .../code-analysis/quality-rules/ca2208.md | 2 +- .../snippets/csharp/all-rules/ca2208.cs | 30 +++++++++---------- ...antiate-argument-exceptions-correctly_1.vb | 30 +++++++++---------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca2208.md b/docs/fundamentals/code-analysis/quality-rules/ca2208.md index 750d5706a6eeb..5db0c69489f03 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca2208.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca2208.md @@ -115,7 +115,7 @@ The following code fixes the previous violation by switching the constructor arg ### Example - paramName doesn't match a method parameter -The following code shows a method that incorrectly throws with a `paramName` that doesn't match any of the method's parameters. The rule fires because `bar` is a local variable, not a method parameter. +The following code shows a method that incorrectly throws with a `paramName` that doesn't match any of the method's parameters. The rule fires because `description` is a local variable, not a method parameter. :::code language="csharp" source="snippets/csharp/all-rules/ca2208.cs" id="snippet3"::: diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2208.cs b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2208.cs index 13db7ff354f6f..f0f0c62f59ea3 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2208.cs +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2208.cs @@ -38,23 +38,23 @@ namespace ca2208_3 { #pragma warning disable CA2208 // Instantiate argument exceptions correctly // - public class Foo + public class Product { - public string? Bar { get; set; } + public string? Description { get; set; } public string Name { get; set; } = string.Empty; } public class Example { - // Violates CA2208: 'bar' is not a parameter of this method. - public void ProcessFoo(Foo foo) + // Violates CA2208: 'description' is not a parameter of this method. + public void ProcessProduct(Product product) { - string? bar = foo.Bar; - if (bar is null) + string? description = product.Description; + if (description is null) { - throw new ArgumentNullException(nameof(bar), $"Foo named {foo.Name} had no Bar!"); + throw new ArgumentNullException(nameof(description), $"Product named {product.Name} had no description!"); } - // Process bar... + // Process description... } } // @@ -64,23 +64,23 @@ public void ProcessFoo(Foo foo) namespace ca2208_4 { // - public class Foo + public class Product { - public string? Bar { get; set; } + public string? Description { get; set; } public string Name { get; set; } = string.Empty; } public class Example { // Fixed: Use InvalidOperationException for invalid object state. - public void ProcessFoo(Foo foo) + public void ProcessProduct(Product product) { - string? bar = foo.Bar; - if (bar is null) + string? description = product.Description; + if (description is null) { - throw new InvalidOperationException($"Foo named {foo.Name} had no Bar!"); + throw new InvalidOperationException($"Product named {product.Name} had no description!"); } - // Process bar... + // Process description... } } // diff --git a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb index 07fda84d30d36..297fc4af3ae48 100644 --- a/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb +++ b/docs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb @@ -55,19 +55,19 @@ End Namespace Namespace ca2208_3 #Disable Warning CA2208 ' Instantiate argument exceptions correctly ' - Public Class Foo - Public Property Bar As String + Public Class Product + Public Property Description As String Public Property Name As String = String.Empty End Class Public Class Example - ' Violates CA2208: 'bar' is not a parameter of this method. - Public Sub ProcessFoo(ByVal foo As Foo) - Dim bar As String = foo.Bar - If bar Is Nothing Then - Throw New ArgumentNullException(NameOf(bar), $"Foo named {foo.Name} had no Bar!") + ' Violates CA2208: 'description' is not a parameter of this method. + Public Sub ProcessProduct(ByVal product As Product) + Dim description As String = product.Description + If description Is Nothing Then + Throw New ArgumentNullException(NameOf(description), $"Product named {product.Name} had no description!") End If - ' Process bar... + ' Process description... End Sub End Class ' @@ -77,19 +77,19 @@ End Namespace Namespace ca2208_4 ' - Public Class Foo - Public Property Bar As String + Public Class Product + Public Property Description As String Public Property Name As String = String.Empty End Class Public Class Example ' Fixed: Use InvalidOperationException for invalid object state. - Public Sub ProcessFoo(ByVal foo As Foo) - Dim bar As String = foo.Bar - If bar Is Nothing Then - Throw New InvalidOperationException($"Foo named {foo.Name} had no Bar!") + Public Sub ProcessProduct(ByVal product As Product) + Dim description As String = product.Description + If description Is Nothing Then + Throw New InvalidOperationException($"Product named {product.Name} had no description!") End If - ' Process bar... + ' Process description... End Sub End Class ' From 2871f73dbc687f2050d2cab6c4d32251f12c9511 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:38:26 -0700 Subject: [PATCH 4/4] Apply suggestions from code review --- .../code-analysis/quality-rules/ca2208.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca2208.md b/docs/fundamentals/code-analysis/quality-rules/ca2208.md index 5db0c69489f03..a7311308b22d7 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca2208.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca2208.md @@ -29,9 +29,8 @@ dev_langs: When a method has a parameter, and it throws an exception type that is, or derives from, , it is expected to call a constructor accepting a `paramName` parameter correctly. Possible causes include the following situations: - A call is made to the default (parameterless) constructor of an exception type that is, or derives from, that also has a constructor that accepts a `paramName` parameter. -- An incorrect string argument is passed to a parameterized constructor of an exception type that is, or derives from, . -- One of the parameters' names is passed for the `message` argument of the constructor of exception type that is, or derives from, . -- The `paramName` argument doesn't match the name of one of the method's parameters. +- An incorrect string argument is passed to a parameterized constructor of an exception type that is, or derives from, . For example, the `paramName` argument doesn't match the name of one of the method's parameters. +- A parameter name is passed for the `message` argument of the constructor of an exception type that is, or derives from, . ## Rule description @@ -48,9 +47,6 @@ The signatures of the one and two string constructors of ) - [`DuplicateWaitObjectException(string parameterName, string message)`]() -> [!IMPORTANT] -> The `paramName` argument passed to or its derived types must match the name of one of the method's parameters. If the null or invalid value isn't from the method's input arguments, use a different exception type. For example, use when an object's state is invalid. - ## How to fix violations To fix a violation of this rule, call a constructor that takes a message, a parameter name, or both, and make sure the arguments are proper for the type of being called. @@ -113,18 +109,14 @@ The following code fixes the previous violation by switching the constructor arg :::code language="vb" source="snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb" id="snippet2"::: -### Example - paramName doesn't match a method parameter - The following code shows a method that incorrectly throws with a `paramName` that doesn't match any of the method's parameters. The rule fires because `description` is a local variable, not a method parameter. :::code language="csharp" source="snippets/csharp/all-rules/ca2208.cs" id="snippet3"::: - :::code language="vb" source="snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb" id="snippet3"::: The following code fixes the previous violation by using instead, which is appropriate when an object's state is invalid. :::code language="csharp" source="snippets/csharp/all-rules/ca2208.cs" id="snippet4"::: - :::code language="vb" source="snippets/vb/all-rules/ca2208-instantiate-argument-exceptions-correctly_1.vb" id="snippet4"::: ## Related rules