RequireNamedArgs 0.0.6
See the version list below for details.
dotnet add package RequireNamedArgs --version 0.0.6
NuGet\Install-Package RequireNamedArgs -Version 0.0.6
<PackageReference Include="RequireNamedArgs" Version="0.0.6" />
paket add RequireNamedArgs --version 0.0.6
#r "nuget: RequireNamedArgs, 0.0.6"
// Install RequireNamedArgs as a Cake Addin
#addin nuget:?package=RequireNamedArgs&version=0.0.6
// Install RequireNamedArgs as a Cake Tool
#tool nuget:?package=RequireNamedArgs&version=0.0.6
Require a method to be invoked with named arguments
Motivation
1. There seems to be a certain level of interest in having a way to force named arguments in C#
2. Say, you're using a builder to create test data to improve your tests
In simpler cases, it's possible to reduce code repetition if you can require named parameters.
For example, let's take a code snippet from the blog post and simplify it:
Here's the original code:
public class AddressDTOBuilder
{
private AddressDTO _entity = new Address;
public AddressBuilder Id(int id)
{
_entity.Id = id;
return this;
}
public AddressBuilder Line1(string line1)
{
_entity.Line1 = line1;
return this;
}
// some methods omitted
public AddressBuilder AttentionTo(string attn)
{
_entity.AttentionTo = attn;
return this;
}
// more methods omitted
public AddressDTO Build()
{
return _entity;
}
// This approach allows easy modification of test values
// Another approach would just have a static method returning AddressDTO
public AddressBuilder WithTestValues()
{
_entity = new AddressDTO
{
Line1 = "12345 Test Street",
Line2 = "3rd Floor",
Line3 = "Suite 300",
AttentionTo = "Test Person",
City = "Test City",
State = "OH",
ZipCode = "43210",
Country = "US",
Description = "Test Description",
Id = Constants.TEST_ADDRESS_ID
}
}
}
And a simplified version:
public class TestAddressDTOBuilder
{
[RequireNamedArgs]
public AddressDTO BuildWith(
string line1 = null,
string line2 = null,
string line3 = null,
string attentionTo = null,
string city = null,
string state = null,
string zipCode = null,
string country = null,
string description = null,
Guid? id = null)
{
var addressDto = new AddressDTO
{
Line1 = line1 ?? "12345 Test Street",
Line2 = line2 ?? "3rd Floor",
Line3 = line3 ?? "Suite 300",
AttentionTo = attentionTo ?? "Test Person",
City = city ?? "Test City",
State = state ?? "OH",
ZipCode = zipCode ?? "43210",
Country = country ?? "US",
Description = description ?? "Test Description",
Id = id ?? Constants.TEST_ADDRESS_ID
};
return addressDto;
}
}
Using the [RequireNamedArgs]
attribute in the above code sample is important as it makes sure a call to BuildWith
uses named arguments.
So something like this is OK:
var testAddressDtoBuilder = new TestAddressDTOBuilder();
// some code skipped...
var addressDto = testAddressDtoBuilder.BuildWith(line3: "Suite 500", state: "WA");
But the analyzer will not allow the code sample below to compile:
var testAddressDtoBuilder = new TestAddressDTOBuilder();
// some code skipped...
var addressDto = testAddressDtoBuilder.BuildWith("54321 Another test street", "9th Floor");
Download and install
Install the RequireNamedArgs nuget package. For example, run the following command in the NuGet Package Manager Console.
Install-Package RequireNamedArgs
This will download all the binaries, and add necessary analyzer references to your project.
How to use it?
- Install the nuget package.
- Introduce
RequireNamedArgsAttribute
attribute to your solution.- e., create your own
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)] public class RequireNamedArgsAttribute : Attribute { }
- Mark methods which should only be invoked with named arguments with a
[RequireNamedArgs]
attribute.
For example:
[RequireNamedArgs]
public static void TellPowerLevel(string name, int powerLevel) {}
// Elsewhere in your code:
// if `TellPowerLevel` method is called with positional arguments,
// the analyzer will emit an error.
TellPowerLevel(name: "Goku", powerLevel: 9001);
Configuration
Starting in Visual Studio 2019 version 16.3, you can configure the severity of analyzer rules, or diagnostics, in an EditorConfig file, from the light bulb menu, and the error list.
Add the following to the [*.cs]
section of your .editorconfig.
[*.cs]
dotnet_diagnostic.RequireNamedArgs.severity = error
The possible severity values are:
error
warning
suggestion
silent
none
default
(in case of this analyzer, it's equal toerror
)
Please take a look at the documentation for a detailed description.
How does it work?
- This analyzer looks at an invocation expression (e.g., a method call).
- It then finds the method's definition.
- If the definition is marked with a
[RequireNamedArgs]
attribute,
the analyzer requires every caller to provide names for the invocation's arguments. - If the last parameter is
params
, the analyzer
doesn't emit the diagnostic, as C# doesn't allow named arguments in this case.
Technical details
The analyzer, code-fix provider, and tests are implemented in F#
Thank you!
- John Koerner for Creating a Code Analyzer using F#
- Dustin Campbell for CSharpEssentials
- Alireza Habibi for CSharpUseNamedArgumentsCodeRefactoringProvider which provided very useful code examples.
- Steve Smith for his article Improve Tests with the Builder Pattern for Test Data.
License
The RequireNamedArgs analyzer and code-fix provider are licensed under the MIT license.
So they can be used freely in commercial applications.
Learn more about Target Frameworks and .NET Standard.
-
- FSharp.Core (>= 4.5.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
- Added support for the implicit object creation syntax;
- Added support for an attribute's constructors;
- Enabled concurrent execution;
- Explicitly disabled generated code analysis.