Skip to content

Commit 47f495c

Browse files
committed
Improved nullability annotations in commands
1 parent 77b0ae2 commit 47f495c

File tree

5 files changed

+28
-28
lines changed

5 files changed

+28
-28
lines changed

Microsoft.Toolkit.Mvvm/Input/AsyncRelayCommand.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ private set
122122
}
123123

124124
/// <inheritdoc/>
125-
public bool CanBeCanceled => !(this.cancelableExecute is null) && IsRunning;
125+
public bool CanBeCanceled => this.cancelableExecute is not null && IsRunning;
126126

127127
/// <inheritdoc/>
128128
public bool IsCancellationRequested => this.cancellationTokenSource?.IsCancellationRequested == true;
@@ -155,7 +155,7 @@ public Task ExecuteAsync(object? parameter)
155155
if (CanExecute(parameter))
156156
{
157157
// Non cancelable command delegate
158-
if (!(this.execute is null))
158+
if (this.execute is not null)
159159
{
160160
return ExecutionTask = this.execute();
161161
}

Microsoft.Toolkit.Mvvm/Input/AsyncRelayCommand{T}.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ public sealed class AsyncRelayCommand<T> : ObservableObject, IAsyncRelayCommand<
1919
/// <summary>
2020
/// The <see cref="Func{TResult}"/> to invoke when <see cref="Execute(T)"/> is used.
2121
/// </summary>
22-
private readonly Func<T, Task>? execute;
22+
private readonly Func<T?, Task>? execute;
2323

2424
/// <summary>
2525
/// The cancelable <see cref="Func{T1,T2,TResult}"/> to invoke when <see cref="Execute(object?)"/> is used.
2626
/// </summary>
27-
private readonly Func<T, CancellationToken, Task>? cancelableExecute;
27+
private readonly Func<T?, CancellationToken, Task>? cancelableExecute;
2828

2929
/// <summary>
3030
/// The optional action to invoke when <see cref="CanExecute(T)"/> is used.
3131
/// </summary>
32-
private readonly Predicate<T>? canExecute;
32+
private readonly Predicate<T?>? canExecute;
3333

3434
/// <summary>
3535
/// The <see cref="CancellationTokenSource"/> instance to use to cancel <see cref="cancelableExecute"/>.
@@ -44,7 +44,7 @@ public sealed class AsyncRelayCommand<T> : ObservableObject, IAsyncRelayCommand<
4444
/// </summary>
4545
/// <param name="execute">The execution logic.</param>
4646
/// <remarks>See notes in <see cref="RelayCommand{T}(Action{T})"/>.</remarks>
47-
public AsyncRelayCommand(Func<T, Task> execute)
47+
public AsyncRelayCommand(Func<T?, Task> execute)
4848
{
4949
this.execute = execute;
5050
}
@@ -54,7 +54,7 @@ public AsyncRelayCommand(Func<T, Task> execute)
5454
/// </summary>
5555
/// <param name="cancelableExecute">The cancelable execution logic.</param>
5656
/// <remarks>See notes in <see cref="RelayCommand{T}(Action{T})"/>.</remarks>
57-
public AsyncRelayCommand(Func<T, CancellationToken, Task> cancelableExecute)
57+
public AsyncRelayCommand(Func<T?, CancellationToken, Task> cancelableExecute)
5858
{
5959
this.cancelableExecute = cancelableExecute;
6060
}
@@ -65,7 +65,7 @@ public AsyncRelayCommand(Func<T, CancellationToken, Task> cancelableExecute)
6565
/// <param name="execute">The execution logic.</param>
6666
/// <param name="canExecute">The execution status logic.</param>
6767
/// <remarks>See notes in <see cref="RelayCommand{T}(Action{T})"/>.</remarks>
68-
public AsyncRelayCommand(Func<T, Task> execute, Predicate<T> canExecute)
68+
public AsyncRelayCommand(Func<T?, Task> execute, Predicate<T?> canExecute)
6969
{
7070
this.execute = execute;
7171
this.canExecute = canExecute;
@@ -77,7 +77,7 @@ public AsyncRelayCommand(Func<T, Task> execute, Predicate<T> canExecute)
7777
/// <param name="cancelableExecute">The cancelable execution logic.</param>
7878
/// <param name="canExecute">The execution status logic.</param>
7979
/// <remarks>See notes in <see cref="RelayCommand{T}(Action{T})"/>.</remarks>
80-
public AsyncRelayCommand(Func<T, CancellationToken, Task> cancelableExecute, Predicate<T> canExecute)
80+
public AsyncRelayCommand(Func<T?, CancellationToken, Task> cancelableExecute, Predicate<T?> canExecute)
8181
{
8282
this.cancelableExecute = cancelableExecute;
8383
this.canExecute = canExecute;
@@ -106,7 +106,7 @@ private set
106106
}
107107

108108
/// <inheritdoc/>
109-
public bool CanBeCanceled => !(this.cancelableExecute is null) && IsRunning;
109+
public bool CanBeCanceled => this.cancelableExecute is not null && IsRunning;
110110

111111
/// <inheritdoc/>
112112
public bool IsCancellationRequested => this.cancellationTokenSource?.IsCancellationRequested == true;
@@ -122,7 +122,7 @@ public void NotifyCanExecuteChanged()
122122

123123
/// <inheritdoc/>
124124
[MethodImpl(MethodImplOptions.AggressiveInlining)]
125-
public bool CanExecute(T parameter)
125+
public bool CanExecute(T? parameter)
126126
{
127127
return this.canExecute?.Invoke(parameter) != false;
128128
}
@@ -138,29 +138,29 @@ parameter is null &&
138138
return true;
139139
}
140140

141-
return CanExecute((T)parameter!);
141+
return CanExecute((T?)parameter);
142142
}
143143

144144
/// <inheritdoc/>
145145
[MethodImpl(MethodImplOptions.AggressiveInlining)]
146-
public void Execute(T parameter)
146+
public void Execute(T? parameter)
147147
{
148148
ExecuteAsync(parameter);
149149
}
150150

151151
/// <inheritdoc/>
152152
public void Execute(object? parameter)
153153
{
154-
ExecuteAsync((T)parameter!);
154+
ExecuteAsync((T?)parameter);
155155
}
156156

157157
/// <inheritdoc/>
158-
public Task ExecuteAsync(T parameter)
158+
public Task ExecuteAsync(T? parameter)
159159
{
160160
if (CanExecute(parameter))
161161
{
162162
// Non cancelable command delegate
163-
if (!(this.execute is null))
163+
if (this.execute is not null)
164164
{
165165
return ExecutionTask = this.execute(parameter);
166166
}
@@ -182,7 +182,7 @@ public Task ExecuteAsync(T parameter)
182182
/// <inheritdoc/>
183183
public Task ExecuteAsync(object? parameter)
184184
{
185-
return ExecuteAsync((T)parameter!);
185+
return ExecuteAsync((T?)parameter);
186186
}
187187

188188
/// <inheritdoc/>

Microsoft.Toolkit.Mvvm/Input/Interfaces/IAsyncRelayCommand{T}.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ public interface IAsyncRelayCommand<in T> : IAsyncRelayCommand, IRelayCommand<T>
1818
/// </summary>
1919
/// <param name="parameter">The input parameter.</param>
2020
/// <returns>The <see cref="Task"/> representing the async operation being executed.</returns>
21-
Task ExecuteAsync(T parameter);
21+
Task ExecuteAsync(T? parameter);
2222
}
2323
}

Microsoft.Toolkit.Mvvm/Input/Interfaces/IRelayCommand{T}.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ public interface IRelayCommand<in T> : IRelayCommand
1818
/// <param name="parameter">The input parameter.</param>
1919
/// <returns>Whether or not the current command can be executed.</returns>
2020
/// <remarks>Use this overload to avoid boxing, if <typeparamref name="T"/> is a value type.</remarks>
21-
bool CanExecute(T parameter);
21+
bool CanExecute(T? parameter);
2222

2323
/// <summary>
2424
/// Provides a strongly-typed variant of <see cref="ICommand.Execute(object)"/>.
2525
/// </summary>
2626
/// <param name="parameter">The input parameter.</param>
2727
/// <remarks>Use this overload to avoid boxing, if <typeparamref name="T"/> is a value type.</remarks>
28-
void Execute(T parameter);
28+
void Execute(T? parameter);
2929
}
3030
}

Microsoft.Toolkit.Mvvm/Input/RelayCommand{T}.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ public sealed class RelayCommand<T> : IRelayCommand<T>
2424
/// <summary>
2525
/// The <see cref="Action"/> to invoke when <see cref="Execute(T)"/> is used.
2626
/// </summary>
27-
private readonly Action<T> execute;
27+
private readonly Action<T?> execute;
2828

2929
/// <summary>
3030
/// The optional action to invoke when <see cref="CanExecute(T)"/> is used.
3131
/// </summary>
32-
private readonly Predicate<T>? canExecute;
32+
private readonly Predicate<T?>? canExecute;
3333

3434
/// <inheritdoc/>
3535
public event EventHandler? CanExecuteChanged;
@@ -43,7 +43,7 @@ public sealed class RelayCommand<T> : IRelayCommand<T>
4343
/// nullable <see cref="object"/> parameter, it is recommended that if <typeparamref name="T"/> is a reference type,
4444
/// you should always declare it as nullable, and to always perform checks within <paramref name="execute"/>.
4545
/// </remarks>
46-
public RelayCommand(Action<T> execute)
46+
public RelayCommand(Action<T?> execute)
4747
{
4848
this.execute = execute;
4949
}
@@ -54,7 +54,7 @@ public RelayCommand(Action<T> execute)
5454
/// <param name="execute">The execution logic.</param>
5555
/// <param name="canExecute">The execution status logic.</param>
5656
/// <remarks>See notes in <see cref="RelayCommand{T}(Action{T})"/>.</remarks>
57-
public RelayCommand(Action<T> execute, Predicate<T> canExecute)
57+
public RelayCommand(Action<T?> execute, Predicate<T?> canExecute)
5858
{
5959
this.execute = execute;
6060
this.canExecute = canExecute;
@@ -68,7 +68,7 @@ public void NotifyCanExecuteChanged()
6868

6969
/// <inheritdoc/>
7070
[MethodImpl(MethodImplOptions.AggressiveInlining)]
71-
public bool CanExecute(T parameter)
71+
public bool CanExecute(T? parameter)
7272
{
7373
return this.canExecute?.Invoke(parameter) != false;
7474
}
@@ -83,12 +83,12 @@ parameter is null &&
8383
return true;
8484
}
8585

86-
return CanExecute((T)parameter!);
86+
return CanExecute((T?)parameter);
8787
}
8888

8989
/// <inheritdoc/>
9090
[MethodImpl(MethodImplOptions.AggressiveInlining)]
91-
public void Execute(T parameter)
91+
public void Execute(T? parameter)
9292
{
9393
if (CanExecute(parameter))
9494
{
@@ -99,7 +99,7 @@ public void Execute(T parameter)
9999
/// <inheritdoc/>
100100
public void Execute(object? parameter)
101101
{
102-
Execute((T)parameter!);
102+
Execute((T?)parameter);
103103
}
104104
}
105105
}

0 commit comments

Comments
 (0)