C#idiomatic C#
ca1877fundamentals/code-analysis/quality-rules

Code analysis

CA1877: Use 'Path.Combine' or 'Path.Join' overloads

Learn about code analysis rule CA1877: Use 'Path.Combine' or 'Path.Join' overloads

CA1877 Performance enabled by default in .NET 10: As suggestion
Fix is breaking or non-breaking Non-breakingApplicable languages C# and Visual Basic

Cause

Multiple consecutive System.IO.Path.Combine or System.IO.Path.Join operations are used to build a path.

Rule description

When you use multiple consecutive Path.Combine or Path.Join operations, it's more efficient to use an overload that accepts multiple path segments. This approach reduces the number of allocations and function calls, improving performance. Both methods provide overloads that accept multiple parameters, allowing you to collapse consecutive operations into a single call.

How to fix violations

Replace consecutive Path.Combine or Path.Join operations with a single call using an overload that accepts all path segments.

A code fix that automatically performs this transformation is available.

Example

The following code snippet shows a violation of CA1877:

sample · csharpdocs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/CA1877.csViolation

csharp
using System.IO;

class ViolationExample
{
    // <Violation>
    public string GetFilePath(string folder, string subfolder, string filename)
    {
        // Violation.
        string temp = Path.Combine(folder, subfolder);
        return Path.Combine(temp, filename);
    }

    public string GetLogPath(string baseDir, string date, string category)
    {
        // Violation.
        return Path.Join(Path.Join(baseDir, date), category);
    }
    // </Violation>
}

class FixExample
{
    // <Fix>
    public string GetFilePath(string folder, string subfolder, string filename)
    {
        // No violation.
        return Path.Combine(folder, subfolder, filename);
    }

    public string GetLogPath(string baseDir, string date, string category)
    {
        // No violation.
        return Path.Join(baseDir, date, category);
    }
    // </Fix>
}

sample · vbdocs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/CA1877.vbViolation

vb
Imports System.IO

Class ViolationExample
    ' <Violation>
    Public Function GetFilePath(folder As String, subfolder As String, filename As String) As String
        ' Violation.
        Dim temp As String = Path.Combine(folder, subfolder)
        Return Path.Combine(temp, filename)
    End Function

    Public Function GetLogPath(baseDir As String, [date] As String, category As String) As String
        ' Violation.
        Return Path.Join(Path.Join(baseDir, [date]), category)
    End Function
    ' </Violation>
End Class

Class FixExample
    ' <Fix>
    Public Function GetFilePath(folder As String, subfolder As String, filename As String) As String
        ' No violation.
        Return Path.Combine(folder, subfolder, filename)
    End Function

    Public Function GetLogPath(baseDir As String, [date] As String, category As String) As String
        ' No violation.
        Return Path.Join(baseDir, [date], category)
    End Function
    ' </Fix>
End Class

The following code snippet fixes the violation:

sample · csharpdocs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/CA1877.csFix

csharp
using System.IO;

class ViolationExample
{
    // <Violation>
    public string GetFilePath(string folder, string subfolder, string filename)
    {
        // Violation.
        string temp = Path.Combine(folder, subfolder);
        return Path.Combine(temp, filename);
    }

    public string GetLogPath(string baseDir, string date, string category)
    {
        // Violation.
        return Path.Join(Path.Join(baseDir, date), category);
    }
    // </Violation>
}

class FixExample
{
    // <Fix>
    public string GetFilePath(string folder, string subfolder, string filename)
    {
        // No violation.
        return Path.Combine(folder, subfolder, filename);
    }

    public string GetLogPath(string baseDir, string date, string category)
    {
        // No violation.
        return Path.Join(baseDir, date, category);
    }
    // </Fix>
}

sample · vbdocs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/CA1877.vbFix

vb
Imports System.IO

Class ViolationExample
    ' <Violation>
    Public Function GetFilePath(folder As String, subfolder As String, filename As String) As String
        ' Violation.
        Dim temp As String = Path.Combine(folder, subfolder)
        Return Path.Combine(temp, filename)
    End Function

    Public Function GetLogPath(baseDir As String, [date] As String, category As String) As String
        ' Violation.
        Return Path.Join(Path.Join(baseDir, [date]), category)
    End Function
    ' </Violation>
End Class

Class FixExample
    ' <Fix>
    Public Function GetFilePath(folder As String, subfolder As String, filename As String) As String
        ' No violation.
        Return Path.Combine(folder, subfolder, filename)
    End Function

    Public Function GetLogPath(baseDir As String, [date] As String, category As String) As String
        ' No violation.
        Return Path.Join(baseDir, [date], category)
    End Function
    ' </Fix>
End Class

When to suppress warnings

It's safe to suppress a warning from this rule if performance isn't a concern.

Suppress a warning

If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.

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

To disable the rule for a file, folder, or project, set its severity to none in the configuration file.

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

For more information, see How to suppress code analysis warnings.

See also