Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/fundamentals/code-analysis/quality-rules/ca1045.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ Passing types by reference (using `out` or `ref`) requires experience with point

When a reference type is passed "by reference," the method intends to use the parameter to return a different instance of the object. (Passing a reference type by reference is also known as using a double pointer, pointer to a pointer, or double indirection.) Using the default calling convention, which is pass "by value," a parameter that takes a reference type already receives a pointer to the object. The pointer, not the object to which it points, is passed by value. Passing by value means that the method cannot change the pointer to have it point to a new instance of the reference type, but can change the contents of the object to which it points. For most applications this is sufficient and yields the behavior that you want.

If a method must return a different instance, use the return value of the method to accomplish this. See the <xref:System.String?displayProperty=fullName> class for a variety of methods that operate on strings and return a new instance of a string. By using this model, it is left to the caller to decide whether the original object is preserved.
If a method must return a different instance, use the return value of the method to accomplish this. For methods that operate on strings and return a new instance of a string, see the <xref:System.String?displayProperty=fullName> class. By using this model, it is left to the caller to decide whether the original object is preserved.

Although return values are commonplace and heavily used, the correct application of `out` and `ref` parameters requires intermediate design and coding skills. Library architects who design for a general audience should not expect users to become proficient in working with `out` or `ref` parameters.

> [!NOTE]
> When you work with parameters that are large structures, the additional resources that are required to copy these structures could cause a performance effect when you pass by value. In these cases, you might consider using `ref` or `out` parameters.
> When you work with parameters that are large structures, the additional resources that are required to copy these structures could have a performance effect when you pass by value. In these cases, you might consider using `ref` or `out` parameters.

## How to fix violations

To fix a violation of this rule that is caused by a value type, have the method return the object as its return value. If the method must return multiple values, redesign it to return a single instance of an object that holds the values.
To fix a violation of this rule that's caused by a value type, have the method return the object as its return value. If the method must return multiple values, redesign it to return a single instance of an object that holds the values.

To fix a violation of this rule that is caused by a reference type, make sure that the behavior that you want is to return a new instance of the reference. If it is, the method should use its return value to do this.
To fix a violation of this rule that's caused by a reference type, make sure that the behavior that you want is to return a new instance of the reference. If it is, the method should use its return value to do this.

## When to suppress warnings

Expand Down
23 changes: 6 additions & 17 deletions docs/fundamentals/code-analysis/quality-rules/ca1806.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ There are several possible reasons for this warning:

- A new object is created but never used.
- A method that creates and returns a new string is called and the new string is never used.
- A COM or P/Invoke method that returns a `HRESULT` or error code that's never used.
- A language-integrated query (LINQ) method that returns a result that's never used.
- A COM or P/Invoke method returns a `HRESULT` or error code that's never used.
- A language-integrated query (LINQ) method returns a result that's never used.

## Rule description

Expand Down Expand Up @@ -110,33 +110,22 @@ dotnet_code_quality.CA1806.additional_use_results_methods = M:MyNamespace.MyType
The following example shows a class that ignores the result of calling <xref:System.String.Trim%2A?displayProperty=nameWithType>.

:::code language="csharp" source="snippets/csharp/all-rules/ca1806.cs" id="snippet1":::

:::code language="vb" source="snippets/vb/all-rules/ca1806-do-not-ignore-method-results_1.vb" id="snippet1":::

## Example 2

The following example fixes the [Example 1](#example-1) violation by assigning the result of <xref:System.String.Trim%2A?displayProperty=nameWithType> back to the variable it was called on.
The following example fixes the violation by assigning the result of <xref:System.String.Trim%2A?displayProperty=nameWithType> back to the variable it was called on.

:::code language="csharp" source="snippets/csharp/all-rules/ca1806.cs" id="snippet2":::

:::code language="vb" source="snippets/vb/all-rules/ca1806-do-not-ignore-method-results_1.vb" id="snippet2":::

## Example 3
## Example 2

The following example shows a method that does not use an object that it creates.
The following example shows a method that doesn't use an object that it creates.

> [!NOTE]
> This violation cannot be reproduced in Visual Basic.

:::code language="csharp" source="snippets/csharp/all-rules/ca1806.cs" id="snippet3":::

## Example 4

The following example fixes the [Example 3](#example-3) violation by removing the unnecessary creation of an object.
The following example fixes the violation by removing the unnecessary creation of an object.

:::code language="csharp" source="snippets/csharp/all-rules/ca1806.cs" id="snippet4":::

<!-- Examples don't exist for the following...
The following example shows a method that ignores the error code that the native method GetShortPathName returns.
The following example fixes the previous violation by checking the error code and throwing an exception when the call fails.
-->
2 changes: 1 addition & 1 deletion docs/fundamentals/code-analysis/quality-rules/ca1816.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Violations of this rule can be caused by:

## Rule description

The <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method lets users release resources at any time before the object becoming available for garbage collection. If the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method is called, it frees resources of the object. This makes finalization unnecessary. <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> should call <xref:System.GC.SuppressFinalize%2A?displayProperty=nameWithType> so the garbage collector doesn't call the finalizer of the object.
The <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method lets users release resources at any time before the object becomes available for garbage collection. If the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method is called, it frees resources of the object. This makes finalization unnecessary. <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> should call <xref:System.GC.SuppressFinalize%2A?displayProperty=nameWithType> so the garbage collector doesn't call the finalizer of the object.

To prevent derived types with finalizers from having to reimplement <xref:System.IDisposable> and to call it, unsealed types without finalizers should still call <xref:System.GC.SuppressFinalize%2A?displayProperty=nameWithType>.

Expand Down
6 changes: 3 additions & 3 deletions docs/fundamentals/code-analysis/quality-rules/ca2100.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "CA2100: Review SQL queries for security vulnerabilities (code analysis)"
description: "Learn about code analysis rule CA2100: Review SQL queries for security vulnerabilities"
ms.date: 11/04/2016
ms.date: 09/24/2025
f1_keywords:
- Review SQL queries for security vulnerabilities
- ReviewSqlQueriesForSecurityVulnerabilities
Expand Down Expand Up @@ -37,7 +37,7 @@ This rule assumes that any string whose value can't be determined at compile tim
- Use a parameterized command string.
- Validate the user input for both type and content before you build the command string.

The following .NET types implement the <xref:System.Data.IDbCommand.CommandText%2A> property or provide constructors that set the property by using a string argument.
The following .NET types implement the <xref:System.Data.IDbCommand.CommandText%2A> property or provide constructors that set the property by using a string argument:

- <xref:System.Data.Odbc.OdbcCommand?displayProperty=fullName> and <xref:System.Data.Odbc.OdbcDataAdapter?displayProperty=fullName>
- <xref:System.Data.OleDb.OleDbCommand?displayProperty=fullName> and <xref:System.Data.OleDb.OleDbDataAdapter?displayProperty=fullName>
Expand All @@ -64,7 +64,7 @@ To fix a violation of this rule, use a parameterized query.

## When to suppress warnings

It is safe to suppress a warning from this rule if the command text does not contain any user input.
It's safe to suppress a warning from this rule if the command text does not contain any user input.

## Suppress a warning

Expand Down
1 change: 0 additions & 1 deletion docs/fundamentals/code-analysis/quality-rules/ca2235.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ For more information, see [How to suppress code analysis warnings](../suppress-w
The following example shows two types: one that violates the rule and one that satisfies the rule.

:::code language="csharp" source="snippets/csharp/all-rules/ca2235.cs" id="snippet1":::

:::code language="vb" source="snippets/vb/all-rules/ca2235-mark-all-non-serializable-fields_1.vb":::

## Remarks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ dotnet_diagnostic.CA1822.severity = none

# CA2200: Rethrow to preserve stack details
dotnet_diagnostic.CA2200.severity = suggestion

# CA2100
dotnet_diagnostic.CA2100.severity = warning
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;

namespace ca1001
{
Expand All @@ -8,7 +8,7 @@ public class MutableItems
{
// CA1002: Change 'List<string>' in 'MutableItems.Items' to
// use 'Collection<T>', 'ReadOnlyCollection<T>' or 'KeyedCollection<K,V>'.
public List<string> Items { get; } = new List<string>();
public List<string> Items { get; } = [];

public void Add(string item)
{
Expand All @@ -19,7 +19,7 @@ public void Add(string item)
// This class satisfies the rule.
public class ReadOnlyItems
{
private readonly List<string> _items = new List<string>();
private readonly List<string> _items = [];

public IReadOnlyCollection<string> Items => _items.AsReadOnly();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public DateTime GetScheduleTime()
// Time-consuming method that is called by GetCustomerHistory.
Appointment[] LoadHistoryFromDB(long customerID)
{
ArrayList records = new ArrayList();
ArrayList records = [];
// Load from database.
return (Appointment[])records.ToArray();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;

namespace ca1031
Expand All @@ -7,14 +7,14 @@ namespace ca1031
// Creates two violations of the rule.
public class GenericExceptionsCaught
{
FileStream? inStream;
FileStream? outStream;
private readonly FileStream? _inStream;
private readonly FileStream? _outStream;

public GenericExceptionsCaught(string inFile, string outFile)
{
try
{
inStream = File.Open(inFile, FileMode.Open);
_inStream = File.Open(inFile, FileMode.Open);
}
catch (SystemException)
{
Expand All @@ -23,7 +23,7 @@ public GenericExceptionsCaught(string inFile, string outFile)

try
{
outStream = File.Open(outFile, FileMode.Open);
_outStream = File.Open(outFile, FileMode.Open);
}
catch
{
Expand All @@ -34,28 +34,28 @@ public GenericExceptionsCaught(string inFile, string outFile)

public class GenericExceptionsCaughtFixed
{
FileStream? inStream;
FileStream outStream;
private readonly FileStream? _inStream;
private readonly FileStream _outStream;

public GenericExceptionsCaughtFixed(string inFile, string outFile)
{
try
{
inStream = File.Open(inFile, FileMode.Open);
_inStream = File.Open(inFile, FileMode.Open);
}

// Fix the first violation by catching a specific exception.
catch (FileNotFoundException)
{
Console.WriteLine($"Unable to open {inFile}.");
};
}

// For functionally equivalent code, also catch
// remaining exceptions that may be thrown by File.Open

try
{
outStream = File.Open(outFile, FileMode.Open);
_outStream = File.Open(outFile, FileMode.Open);
}

// Fix the second violation by rethrowing the generic
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Runtime.Serialization;

namespace ca1032
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Globalization;

//<snippet1>
Expand Down Expand Up @@ -99,11 +99,11 @@ public override int GetHashCode()
}
public static bool operator <(RatingInformation left, RatingInformation right)
{
return (Compare(left, right) < 0);
return Compare(left, right) < 0;
}
public static bool operator >(RatingInformation left, RatingInformation right)
{
return (Compare(left, right) > 0);
return Compare(left, right) > 0;
}
}
//</snippet1>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;

namespace ca1045
{
Expand Down Expand Up @@ -26,11 +26,12 @@ public class BadRefAndOut
public static bool ReplyInformation(TypeOfFeedback input,
out string reply, ref Actions action)
{
bool returnReply = false;
string replyText = "Your feedback has been forwarded " +
"to the product manager.";
string replyText = """
Your feedback has been forwarded to the product manager.
""";

reply = String.Empty;
reply = string.Empty;
bool returnReply;
switch (input)
{
case TypeOfFeedback.Complaint:
Expand All @@ -57,66 +58,33 @@ public static bool ReplyInformation(TypeOfFeedback input,
// Redesigned version does not use out or ref parameters;
// instead, it returns this container type.

public class ReplyData
public record class ReplyData(string Reply, Actions Action, bool ReturnReply = false)
{
string reply;
Actions action;
bool returnReply;

// Constructors.
public ReplyData()
{
this.reply = String.Empty;
this.action = Actions.Discard;
this.returnReply = false;
}

public ReplyData(Actions action, string reply, bool returnReply)
{
this.reply = reply;
this.action = action;
this.returnReply = returnReply;
}

// Properties.
public string Reply { get { return reply; } }
public Actions Action { get { return action; } }

public override string ToString()
{
return String.Format("Reply: {0} Action: {1} return? {2}",
reply, action.ToString(), returnReply.ToString());
return string.Format("Reply: {0} Action: {1} return? {2}",
Reply, Action.ToString(), ReturnReply.ToString());
}
}

public class RedesignedRefAndOut
{
public static ReplyData ReplyInformation(TypeOfFeedback input)
public static ReplyData? ReplyInformation(TypeOfFeedback input)
{
ReplyData answer;
string replyText = "Your feedback has been forwarded " +
"to the product manager.";

switch (input)
ReplyData? answer = input switch
{
case TypeOfFeedback.Complaint:
case TypeOfFeedback.Praise:
answer = new ReplyData(
Actions.ForwardToManagement,
"Thank you. " + replyText,
true);
break;
case TypeOfFeedback.Suggestion:
answer = new ReplyData(
Actions.ForwardToDeveloper,
replyText,
true);
break;
case TypeOfFeedback.Incomprehensible:
default:
answer = new ReplyData();
break;
}
TypeOfFeedback.Complaint or TypeOfFeedback.Praise => new ReplyData(
"Thank you. " + replyText,
Actions.ForwardToManagement,
true),
TypeOfFeedback.Suggestion => new ReplyData(
replyText,
Actions.ForwardToDeveloper,
true),
_ => null,
};
return answer;
}
}
Expand All @@ -133,13 +101,13 @@ static void UseTheComplicatedClass()
string[] reply = new string[5];

// You must initialize a ref parameter.
Actions[] action = {Actions.Unknown,Actions.Unknown,
Actions[] action = [Actions.Unknown,Actions.Unknown,
Actions.Unknown,Actions.Unknown,
Actions.Unknown,Actions.Unknown};
Actions.Unknown,Actions.Unknown];
bool[] disposition = new bool[5];
int i = 0;

foreach (TypeOfFeedback t in Enum.GetValues(typeof(TypeOfFeedback)))
foreach (TypeOfFeedback t in Enum.GetValues<TypeOfFeedback>())
{
// The call to the library.
disposition[i] = BadRefAndOut.ReplyInformation(
Expand All @@ -153,7 +121,7 @@ static void UseTheSimplifiedClass()
{
ReplyData[] answer = new ReplyData[5];
int i = 0;
foreach (TypeOfFeedback t in Enum.GetValues(typeof(TypeOfFeedback)))
foreach (TypeOfFeedback t in Enum.GetValues<TypeOfFeedback>())
{
// The call to the library.
answer[i] = RedesignedRefAndOut.ReplyInformation(t);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;

namespace ca1046
{
Expand All @@ -24,8 +24,8 @@ public class ReferenceTypeEquality
{
public static void Main1046()
{
MyReferenceType a = new MyReferenceType(2, 2);
MyReferenceType b = new MyReferenceType(2, 2);
MyReferenceType a = new(2, 2);
MyReferenceType b = new(2, 2);
MyReferenceType c = a;

Console.WriteLine($"a = new {a} and b = new {b} are equal? {(a.Equals(b) ? "Yes" : "No")}");
Expand Down
Loading