PrismLibrary/Prism · error · ArgumentNullException

Resources.DelegateCommandDelegatesCannotBeNull

Error message

Resources.DelegateCommandDelegatesCannotBeNull

What it means

The generic DelegateCommand<T>'s two-argument constructor requires non-null execute (Action<T>) and canExecute (Func<T,bool>) delegates and throws ArgumentNullException with Resources.DelegateCommandDelegatesCannotBeNull when either is null.

Solutions

  1. Provide non-null execute and canExecute delegates at construction.
  2. Initialize handler fields before command construction.
  3. Use the single-delegate constructor when only execute is available; note T must be object or Nullable<> per the generic checks.

Example fix

// before
SelectCommand = new DelegateCommand<Item>(_selectHandler); // via (item, null) ctor path handler null
// after
SelectCommand = new DelegateCommand<Item>(Select, item => item != null);
Defensive patterns

Strategy: validation

Validate before calling

if (execute != null && canExecute != null)
    Cmd = new DelegateCommand<T>(execute, canExecute);

Type guard

bool CanBuild<T>(Action<T> exec, Func<T, bool> canExec) => exec != null && canExec != null;

Try / catch

try { SelectCommand = new DelegateCommand<Item>(Select, CanSelect); }
catch (ArgumentNullException ex) { logger.LogError(ex, "DelegateCommand<T> delegate null"); }

Prevention

When it happens

Trigger: new DelegateCommand<T>(null, canExecute) or new DelegateCommand<T>(execute, null); delegates sourced from nullable fields, reflection, or DI that are null at construction time.

Common situations: Typed ViewModel commands built from handlers assigned later; refactors changing method signatures; DI registration mistakes returning null handlers.

Related errors


AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15). Data as JSON: /api/errors/56f6d90742128dac. Report an issue: GitHub.

Appendix: source

Thrown at src/Prism.Core/Commands/DelegateCommand{T}.cs:60

        /// </summary>
        /// <param name="executeMethod">Delegate to execute when Execute is called on the command. This can be null to just hook up a CanExecute delegate.</param>
        /// <remarks><see cref="CanExecute(T)"/> will always return true.</remarks>
        public DelegateCommand(Action<T> executeMethod)
            : this(executeMethod, (o) => true)
        {
        }

        /// <summary>
        /// Initializes a new instance of <see cref="DelegateCommand{T}"/>.
        /// </summary>
        /// <param name="executeMethod">Delegate to execute when Execute is called on the command. This can be null to just hook up a CanExecute delegate.</param>
        /// <param name="canExecuteMethod">Delegate to execute when CanExecute is called on the command. This can be null.</param>
        /// <exception cref="ArgumentNullException">When both <paramref name="executeMethod"/> and <paramref name="canExecuteMethod"/> are <see langword="null" />.</exception>
        public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
            : base()
        {
            if (executeMethod == null || canExecuteMethod == null)
                throw new ArgumentNullException(nameof(executeMethod), Resources.DelegateCommandDelegatesCannotBeNull);

            TypeInfo genericTypeInfo = typeof(T).GetTypeInfo();

            // DelegateCommand allows object or Nullable<>.  
            // note: Nullable<> is a struct so we cannot use a class constraint.
            if (genericTypeInfo.IsValueType)
            {
                if ((!genericTypeInfo.IsGenericType) || (!typeof(Nullable<>).GetTypeInfo().IsAssignableFrom(genericTypeInfo.GetGenericTypeDefinition().GetTypeInfo())))
                {
                    throw new InvalidCastException(Resources.DelegateCommandInvalidGenericPayloadType);
                }
            }

            _executeMethod = executeMethod;
            _canExecuteMethod = canExecuteMethod;
        }

        ///<summary>

View on GitHub (pinned to 358118cd64)