A few years ago, I introduced Simplifying paths handling in .NET code with the FullPath type, a library to ensure you always deal with full paths in your applications and provide common methods to manipulate them easily. Recently, I've added new features to the library, including new methods and a set of Roslyn analyzers to help you use the library correctly.
The main idea of FullPath is to avoid bugs related to relative paths by forcing the use of absolute paths through a dedicated type:
C#
// It automatically calls Path.GetFullPath to resolve the path
FullPath rootPath = FullPath.FromPath("data");
// You can use the / operator to join paths (similar to Path.Combine)
FullPath filePath = rootPath / "projects" / "meziantou.txt";
#New methods
The FullPath struct now includes several With* methods to create a new FullPath from an existing one by changing a part of the path:
WithName(string name): Returns a new FullPath with the specified file or directory name.WithNameWithoutExtension(string nameWithoutExtension): Returns a new FullPath with the specified name, keeping the existing extension.WithExtension(string extension): Returns a new FullPath with the specified extension. It also supports changing multiple extensions (e.g., .tar.gz) using the extensionCount or replaceAllTrailingExtensions parameters.
C#
var path = FullPath.FromPath("archive.tar.gz");
// Change extension to .zip
_ = path.WithExtension(".zip"); // archive.tar.zip
_ = path.WithExtension(".zip", extensionCount: 2); // archive.zip
_ = path.WithExtension(".zip", replaceAllTrailingExtensions: true); // archive.zip
// Change name
_ = path.WithName("newname.txt"); // archive.tar.newname.txt
_ = path.WithNameWithoutExtension("newname"); // archive.tar.newname.gz
#The + operator
In addition to the / operator used to combine paths (similar to Path.Combine), you can now use the + operator to append a suffix to the current path string. This is useful when you want to add an extension or a suffix to a file name without re-combining paths.
C#
FullPath filePath = FullPath.FromPath("meziantou.txt");
FullPath backupPath = filePath + ".bak"; // meziantou.txt.bak
#Roslyn Analyzers
To help you use FullPath effectively and avoid common pitfalls. The package contains several Roslyn analyzers to ensure you are using the FullPath type where appropriate and avoiding redundant calls to System.IO.Path methods.
Here are some of the rules included:
- MFFP0001: Use FullPath directly instead of Path.GetFullPath
- MFFP0002: Use the right FullPath operand directly
- MFFP0003: Use '/' with a FullPath base instead of Path.GetFullPath
- MFFP0004: Use '/' operator instead of Path.Combine
- MFFP0005: Use FullPath.Name instead of Path.GetFileName
- MFFP0006: Use FullPath.NameWithoutExtension instead of Path.GetFileNameWithoutExtension
- MFFP0007: Use FullPath.Extension instead of Path.GetExtension
- MFFP0008: Use FullPath.Parent instead of Path.GetDirectoryName
- MFFP0009: Use FullPath.ChangeExtension instead of Path.ChangeExtension
- MFFP0010: Use FullPath.MakePathRelativeTo instead of Path.GetRelativePath
- MFFP0011: Return FullPath instead of string
Using these analyzers ensures that your path manipulation code remains clean, efficient, and less prone to errors related to relative paths.
#Additional resources
Do you have a question or a suggestion about this post? Contact me!