Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nullable annotations to commands #2959

Merged
merged 1 commit into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Prism.Core/Commands/AsyncDelegateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public bool CanExecute()
/// Handle the internal invocation of <see cref="ICommand.Execute(object)"/>
/// </summary>
/// <param name="parameter">Command Parameter</param>
protected override async void Execute(object parameter)
protected override async void Execute(object? parameter)
{
await Execute(_getCancellationToken());
}
Expand All @@ -140,7 +140,7 @@ protected override async void Execute(object parameter)
/// </summary>
/// <param name="parameter"></param>
/// <returns><see langword="true"/> if the Command Can Execute, otherwise <see langword="false" /></returns>
protected override bool CanExecute(object parameter)
protected override bool CanExecute(object? parameter)
{
return CanExecute();
}
Expand Down
12 changes: 6 additions & 6 deletions src/Prism.Core/Commands/AsyncDelegateCommand{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ public bool CanExecute(T parameter)
/// Handle the internal invocation of <see cref="ICommand.Execute(object)"/>
/// </summary>
/// <param name="parameter">Command Parameter</param>
protected override async void Execute(object parameter)
protected override async void Execute(object? parameter)
{
try
{
await Execute((T)parameter, _getCancellationToken());
await Execute((T)parameter!, _getCancellationToken());
}
catch (Exception ex)
{
Expand All @@ -152,11 +152,11 @@ protected override async void Execute(object parameter)
/// </summary>
/// <param name="parameter"></param>
/// <returns><see langword="true"/> if the Command Can Execute, otherwise <see langword="false" /></returns>
protected override bool CanExecute(object parameter)
protected override bool CanExecute(object? parameter)
{
try
{
return CanExecute((T)parameter);
return CanExecute((T)parameter!);
}
catch (Exception ex)
{
Expand Down Expand Up @@ -243,7 +243,7 @@ async Task IAsyncCommand.ExecuteAsync(object? parameter)
try
{
// If T is not nullable this may throw an exception
await Execute((T)parameter, _getCancellationToken());
await Execute((T)parameter!, _getCancellationToken());
}
catch (Exception ex)
{
Expand All @@ -259,7 +259,7 @@ async Task IAsyncCommand.ExecuteAsync(object? parameter, CancellationToken cance
try
{
// If T is not nullable this may throw an exception
await Execute((T)parameter, cancellationToken);
await Execute((T)parameter!, cancellationToken);
}
catch (Exception ex)
{
Expand Down
75 changes: 36 additions & 39 deletions src/Prism.Core/Commands/CompositeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,25 @@
using System.Windows.Input;
using Prism.Properties;

#nullable enable
namespace Prism.Commands
{
/// <summary>
/// The CompositeCommand composes one or more ICommands.
/// </summary>
public class CompositeCommand : ICommand
{
private readonly List<ICommand> _registeredCommands = new List<ICommand>();
private readonly List<ICommand> _registeredCommands = new();
private readonly bool _monitorCommandActivity;
private readonly EventHandler _onRegisteredCommandCanExecuteChangedHandler;
private SynchronizationContext _synchronizationContext;
private readonly SynchronizationContext? _synchronizationContext;

/// <summary>
/// Initializes a new instance of <see cref="CompositeCommand"/>.
/// </summary>
public CompositeCommand()
{
this._onRegisteredCommandCanExecuteChangedHandler = new EventHandler(this.OnRegisteredCommandCanExecuteChanged);
_onRegisteredCommandCanExecuteChangedHandler = new EventHandler(OnRegisteredCommandCanExecuteChanged);
_synchronizationContext = SynchronizationContext.Current;
}

Expand All @@ -33,7 +34,7 @@ public CompositeCommand()
public CompositeCommand(bool monitorCommandActivity)
: this()
{
this._monitorCommandActivity = monitorCommandActivity;
_monitorCommandActivity = monitorCommandActivity;
}

/// <summary>
Expand All @@ -53,24 +54,23 @@ public virtual void RegisterCommand(ICommand command)
throw new ArgumentException(Resources.CannotRegisterCompositeCommandInItself);
}

lock (this._registeredCommands)
lock (_registeredCommands)
{
if (this._registeredCommands.Contains(command))
if (_registeredCommands.Contains(command))
{
throw new InvalidOperationException(Resources.CannotRegisterSameCommandTwice);
}
this._registeredCommands.Add(command);
_registeredCommands.Add(command);
}

command.CanExecuteChanged += this._onRegisteredCommandCanExecuteChangedHandler;
this.OnCanExecuteChanged();
command.CanExecuteChanged += _onRegisteredCommandCanExecuteChangedHandler;
OnCanExecuteChanged();

if (this._monitorCommandActivity)
if (_monitorCommandActivity)
{
var activeAwareCommand = command as IActiveAware;
if (activeAwareCommand != null)
if (command is IActiveAware activeAwareCommand)
{
activeAwareCommand.IsActiveChanged += this.Command_IsActiveChanged;
activeAwareCommand.IsActiveChanged += Command_IsActiveChanged;
}
}
}
Expand All @@ -83,30 +83,29 @@ public virtual void UnregisterCommand(ICommand command)
{
if (command == null) throw new ArgumentNullException(nameof(command));
bool removed;
lock (this._registeredCommands)
lock (_registeredCommands)
{
removed = this._registeredCommands.Remove(command);
removed = _registeredCommands.Remove(command);
}

if (removed)
{
command.CanExecuteChanged -= this._onRegisteredCommandCanExecuteChangedHandler;
this.OnCanExecuteChanged();
command.CanExecuteChanged -= _onRegisteredCommandCanExecuteChangedHandler;
OnCanExecuteChanged();

if (this._monitorCommandActivity)
if (_monitorCommandActivity)
{
var activeAwareCommand = command as IActiveAware;
if (activeAwareCommand != null)
if (command is IActiveAware activeAwareCommand)
{
activeAwareCommand.IsActiveChanged -= this.Command_IsActiveChanged;
activeAwareCommand.IsActiveChanged -= Command_IsActiveChanged;
}
}
}
}

private void OnRegisteredCommandCanExecuteChanged(object sender, EventArgs e)
private void OnRegisteredCommandCanExecuteChanged(object? sender, EventArgs e)
{
this.OnCanExecuteChanged();
OnCanExecuteChanged();
}


Expand All @@ -118,18 +117,18 @@ private void OnRegisteredCommandCanExecuteChanged(object sender, EventArgs e)
/// If the command does not require data to be passed, this object can be set to <see langword="null" />.
/// </param>
/// <returns><see langword="true" /> if all of the commands return <see langword="true" />; otherwise, <see langword="false" />.</returns>
public virtual bool CanExecute(object parameter)
public virtual bool CanExecute(object? parameter)
{
bool hasEnabledCommandsThatShouldBeExecuted = false;

ICommand[] commandList;
lock (this._registeredCommands)
lock (_registeredCommands)
{
commandList = this._registeredCommands.ToArray();
commandList = _registeredCommands.ToArray();
}
foreach (ICommand command in commandList)
{
if (this.ShouldExecute(command))
if (ShouldExecute(command))
{
if (!command.CanExecute(parameter))
{
Expand All @@ -146,20 +145,20 @@ public virtual bool CanExecute(object parameter)
/// <summary>
/// Occurs when any of the registered commands raise <see cref="ICommand.CanExecuteChanged"/>.
/// </summary>
public virtual event EventHandler CanExecuteChanged;
public virtual event EventHandler? CanExecuteChanged;

/// <summary>
/// Forwards <see cref="ICommand.Execute"/> to the registered commands.
/// </summary>
/// <param name="parameter">Data used by the command.
/// If the command does not require data to be passed, this object can be set to <see langword="null" />.
/// </param>
public virtual void Execute(object parameter)
public virtual void Execute(object? parameter)
{
Queue<ICommand> commands;
lock (this._registeredCommands)
lock (_registeredCommands)
{
commands = new Queue<ICommand>(this._registeredCommands.Where(this.ShouldExecute).ToList());
commands = new Queue<ICommand>(_registeredCommands.Where(ShouldExecute).ToList());
}

while (commands.Count > 0)
Expand All @@ -174,17 +173,15 @@ public virtual void Execute(object parameter)
/// </summary>
/// <param name="command">The command to evaluate.</param>
/// <returns>A <see cref="bool"/> value indicating whether the command should be used
/// when evaluating <see cref="CompositeCommand.CanExecute"/> and <see cref="CompositeCommand.Execute"/>.</returns>
/// when evaluating <see cref="CanExecute"/> and <see cref="Execute"/>.</returns>
/// <remarks>
/// If this command is set to monitor command activity, and <paramref name="command"/>
/// implements the <see cref="IActiveAware"/> interface,
/// this method will return <see langword="false" /> if the command's <see cref="IActiveAware.IsActive"/>
/// property is <see langword="false" />; otherwise it always returns <see langword="true" />.</remarks>
protected virtual bool ShouldExecute(ICommand command)
{
var activeAwareCommand = command as IActiveAware;

if (this._monitorCommandActivity && activeAwareCommand != null)
if (_monitorCommandActivity && command is IActiveAware activeAwareCommand)
{
return activeAwareCommand.IsActive;
}
Expand All @@ -202,9 +199,9 @@ public IList<ICommand> RegisteredCommands
get
{
IList<ICommand> commandList;
lock (this._registeredCommands)
lock (_registeredCommands)
{
commandList = this._registeredCommands.ToList();
commandList = _registeredCommands.ToList();
}

return commandList;
Expand Down Expand Up @@ -233,9 +230,9 @@ protected virtual void OnCanExecuteChanged()
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">EventArgs to pass to the event.</param>
private void Command_IsActiveChanged(object sender, EventArgs e)
private void Command_IsActiveChanged(object? sender, EventArgs e)
{
this.OnCanExecuteChanged();
OnCanExecuteChanged();
}
}
}
5 changes: 3 additions & 2 deletions src/Prism.Core/Commands/DelegateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Windows.Input;
using Prism.Properties;

#nullable enable
namespace Prism.Commands
{
/// <summary>
Expand Down Expand Up @@ -85,7 +86,7 @@ public bool CanExecute()
/// Handle the internal invocation of <see cref="ICommand.Execute(object)"/>
/// </summary>
/// <param name="parameter">Command Parameter</param>
protected override void Execute(object parameter)
protected override void Execute(object? parameter)
{
Execute();
}
Expand All @@ -95,7 +96,7 @@ protected override void Execute(object parameter)
/// </summary>
/// <param name="parameter"></param>
/// <returns><see langword="true"/> if the Command Can Execute, otherwise <see langword="false" /></returns>
protected override bool CanExecute(object parameter)
protected override bool CanExecute(object? parameter)
{
return CanExecute();
}
Expand Down
23 changes: 12 additions & 11 deletions src/Prism.Core/Commands/DelegateCommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Prism.Common;
using Prism.Mvvm;

#nullable enable
namespace Prism.Commands
{
/// <summary>
Expand All @@ -16,13 +17,13 @@ public abstract class DelegateCommandBase : BindableBase, ICommand, IActiveAware
{
private bool _isActive;

private SynchronizationContext _synchronizationContext;
private readonly HashSet<string> _observedPropertiesExpressions = new HashSet<string>();
private SynchronizationContext? _synchronizationContext;
private readonly HashSet<string> _observedPropertiesExpressions = new();

/// <summary>
/// Provides an Exception Handler to register callbacks or handle encountered exceptions within
/// </summary>
protected readonly MulticastExceptionHandler ExceptionHandler = new MulticastExceptionHandler();
protected readonly MulticastExceptionHandler ExceptionHandler = new();

/// <summary>
/// Creates a new instance of a <see cref="DelegateCommandBase"/>, specifying both the execute action and the can execute function.
Expand All @@ -35,7 +36,7 @@ protected DelegateCommandBase()
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
public virtual event EventHandler CanExecuteChanged;
public virtual event EventHandler? CanExecuteChanged;

/// <summary>
/// Raises <see cref="ICommand.CanExecuteChanged"/> so every
Expand Down Expand Up @@ -64,12 +65,12 @@ public void RaiseCanExecuteChanged()
OnCanExecuteChanged();
}

void ICommand.Execute(object parameter)
void ICommand.Execute(object? parameter)
{
Execute(parameter);
}

bool ICommand.CanExecute(object parameter)
bool ICommand.CanExecute(object? parameter)
{
return CanExecute(parameter);
}
Expand All @@ -78,14 +79,14 @@ bool ICommand.CanExecute(object parameter)
/// Handle the internal invocation of <see cref="ICommand.Execute(object)"/>
/// </summary>
/// <param name="parameter">Command Parameter</param>
protected abstract void Execute(object parameter);
protected abstract void Execute(object? parameter);

/// <summary>
/// Handle the internal invocation of <see cref="ICommand.CanExecute(object)"/>
/// </summary>
/// <param name="parameter"></param>
/// <returns><see langword="true"/> if the Command Can Execute, otherwise <see langword="false" /></returns>
protected abstract bool CanExecute(object parameter);
protected abstract bool CanExecute(object? parameter);

/// <summary>
/// Observes a property that implements INotifyPropertyChanged, and automatically calls DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
Expand All @@ -96,7 +97,7 @@ protected internal void ObservesPropertyInternal<T>(Expression<Func<T>> property
{
if (_observedPropertiesExpressions.Contains(propertyExpression.ToString()))
{
throw new ArgumentException($"{propertyExpression.ToString()} is already being observed.",
throw new ArgumentException($"{propertyExpression} is already being observed.",
nameof(propertyExpression));
}
else
Expand All @@ -121,10 +122,10 @@ public bool IsActive
/// <summary>
/// Fired if the <see cref="IsActive"/> property changes.
/// </summary>
public virtual event EventHandler IsActiveChanged;
public virtual event EventHandler? IsActiveChanged;

/// <summary>
/// This raises the <see cref="DelegateCommandBase.IsActiveChanged"/> event.
/// This raises the <see cref="IsActiveChanged"/> event.
/// </summary>
protected virtual void OnIsActiveChanged()
{
Expand Down