Skip to content

Commit

Permalink
Add nullable annotations to commands
Browse files Browse the repository at this point in the history
  • Loading branch information
bdovaz committed Sep 15, 2023
1 parent 91beae0 commit 264192c
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 75 deletions.
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
Loading

0 comments on commit 264192c

Please sign in to comment.