CommunityToolkit / CommunityToolkit/dotnet

[Feature] Extend Guard Methods to Return Validated Arguments

Open
#1,110 0 comments 3 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
3.8k
Forks
400
PR merge metrics
No merged PRs in 30d

Description

# Proposal: Extend Guard Methods to Return Validated Arguments

# Summary

Extend the existing `Guard` functionality to provide an alternative version of all guard methods that return the validated argument when the validation passes. This enhancement would allow method chaining and inline validation assignments.

# Current Usage

The current `Guard` methods validate an argument and throw an exception if the validation fails, but they return `void`. This requires an extra assignment step when the argument is needed after validation.

## Example:
```
public class Processor
{
private readonly string _input;

public Processor(string input)
{
Guard.IsNotNullOrEmpty(input);
_input = input;
}

public void Print()
{
Console.WriteLine(_input);
}
}
```

# Proposed Enhancement

Provide an alternative version of all guard methods that return the validated argument when the validation passes. This would allow inline validation while preserving the original API behavior.

## Proposed Usage

Instead of requiring a separate assignment, the new API would allow:
```
public class Processor
{
private readonly string _input;

public Processor(string input)
{
_input = Guard.IsNotNullOrEmpty(input);
}

public void Print()
{
Console.WriteLine(_input);
}
}
```
# Implementation Options

Two approaches could be taken to introduce this feature:

## Option 1: Create a `ResultGuard` Class

Introduce a new `ResultGuard` class that mirrors `Guard` but returns the validated argument.
```
public static class ResultGuard
{
public static T IsNotNullOrEmpty(T value, [CallerArgumentExpression("value")] string? paramName = null)
where T : class
{
Guard.IsNotNullOrEmpty(value, paramName);
return value;
}
}

```
**Pros:**

- No changes to the existing `Guard` class.
-
- Clear separation between validation-only (`Guard`) and validation-with-return (`ResultGuard`).

**Cons:**

- Code duplication or the need to refactor `Guard` to reuse logic.
-
- Users must choose between `Guard` and `ResultGuard`.

## Option 2: Modify `Guard` to Return the Argument

Modify the existing `Guard` class to return the argument instead of `void`.
```
public static class Guard
{
public static T IsNotNullOrEmpty(T value, [CallerArgumentExpression("value")] string? paramName = null)
where T : class
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException($"{paramName} cannot be null or empty.", paramName);
}
return value;
}
}
```
**Pros:**

- No need for a new class.
-
- Maintains a single validation API.
-
- Fully backward-compatible since it only extends the return type.

**Cons:**

- Changes the return type of existing methods, which may have unforeseen consequences in certain use cases.

# Personal Preference

I personally prefer Option 2 (modifying `Guard`) because it avoids duplication, maintains backward compatibility, and enhances usability with minimal changes. However, I am open to other suggestions if the maintainers have concerns or alternative approaches in mind.

Would the maintainers be open to this enhancement? If so, I can submit a PR with the implementation.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.