c# - 是否可以减少我在此代码中使用的构造函数的数量?多个类的构造函数重载和转发

标签 c#

我今天早些时候写了这段代码。该代码的目的是实现 ICommand,使其一次只运行一个方法,并为其他方法静默返回。

我编写它是为了与多平台用户界面一起使用,因此不会注册多个按键。

它有很多构造函数,我不太了解这种重载。下学期我将学习设计模式,下学期将学习面向对象编程,所以希望我的代码在那之后会更干净!

有没有办法缩短代码(减少所需构造函数的数量)?

using System;
using Xamarin.Forms;
using System.Windows.Input;
using System.Threading.Tasks;

namespace dobjenkins
{
    public interface IAsyncCommand : ICommand
    {
        Task ExecuteAsync (object parameter);
    }

    public class AsyncCommand : IAsyncCommand
    {
        private readonly Func<object, Task> execute;
        private readonly Func<object, bool> canExecute;

        ///
        /// Constructors and initializors
        ///
        protected AsyncCommand ()
        {
        }

        public AsyncCommand (Func<object, Task> execute, Func<object, bool> canExecute)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        public AsyncCommand (Func<object, Task> execute)
        {
            this.execute = execute;
        }

        public AsyncCommand (Func<Task> execute, Func<bool> canExecute)
        {
            this.execute = _ => execute ();
            this.canExecute = _ => canExecute ();
        }

        public AsyncCommand (Func<Task> execute)
        {
            this.execute = _ => execute ();
        }

        ///
        ///  Execute Methods
        ///


        public async Task ExecuteAsync (object parameter)
        {
            await execute (parameter);
        }

        public async void Execute (object parameter)
        {
            await ExecuteAsync (parameter);
        }


        /// 
        /// CanExecute methods/Event
        ///

        public event EventHandler CanExecuteChanged;

        public void ChangeCanExecute ()
        {
            var ev = CanExecuteChanged;
            if (ev != null) {
                ev (this, EventArgs.Empty);
            }
        }

        public bool CanExecute (object parameter)
        {
            return canExecute == null || canExecute (parameter);
        }
    }

    public sealed class AsyncCommand<T> : AsyncCommand
    {
        private readonly Func<T, Task> execute;
        private readonly Func<T, bool> canExecute;

        public AsyncCommand (Func<T, Task> execute)
        {
            this.execute = execute;
        }

        public AsyncCommand (Func<T, Task> execute, Func<T, bool> canExecute)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        ///
        ///  Execute Methods
        ///

        public async Task ExecuteAsync (T parameter)
        {
            await execute (parameter);
        }

        public async void Execute (T parameter)
        {
            await ExecuteAsync (parameter);
        }

        public bool CanExecute (T parameter)
        {
            return canExecute == null || canExecute (parameter);
        }
    }

    public class ExclusiveCommand : ICommand
    {
        protected ICommand Backing;
        protected static bool IsBusy = false;


        // 
        //  Constructors
        //
        #region Constructors
        public ExclusiveCommand()
        {
        }

        //
        // SYNC (normal) CONSTRUCTORS
        //

        public ExclusiveCommand (Action<object> execute, Func<object, bool> canExecute)
        {
            Backing = new Command (execute, canExecute);
        }

        public ExclusiveCommand (Action<object> execute)
        {
            Backing = new Command (execute);
        }

        public ExclusiveCommand (Action execute, Func<bool> canExecute)
        {
            Backing = new Command (execute, canExecute);
        }

        public ExclusiveCommand (Action execute)
        {
            Backing = new Command (execute);
        }

        //
        // ASYNC CONSTRUCTORS
        //


        public ExclusiveCommand (Func<object, Task> execute, Func<object, bool> canExecute)
        {
            Backing = new AsyncCommand (execute, canExecute);
        }

        public ExclusiveCommand (Func<object, Task> execute)
        {
            Backing = new AsyncCommand (execute);
        }

        public ExclusiveCommand (Func<Task> execute, Func<bool> canExecute)
        {
            Backing = new AsyncCommand (execute, canExecute);
        }

        public ExclusiveCommand (Func<Task> a)
        {
            Backing = new AsyncCommand (a);
        }

        // 
        //  End Constructors
        //
        #endregion Constructors

        // Execute

        public async void Execute (object parameter)
        {
            if (IsBusy) {
                return;
            }
            IsBusy = true;

            var async = Backing as AsyncCommand;
            if (async != null) {
                await async.ExecuteAsync (parameter);
            } else {
                Backing.Execute (parameter);
            }

            IsBusy = false;
        }

        //
        /// Can execute
        //

        public event EventHandler CanExecuteChanged;

        public void ChangeCanExecute ()
        {
            var ev = CanExecuteChanged;
            if (ev != null) {
                ev (this, EventArgs.Empty);
            }
        }

        public bool CanExecute (object parameter)
        {
            return Backing.CanExecute (parameter);
        }
    }
}

public sealed class ExclusiveCommand<T> : ExclusiveCommand
{
    /// 
    ///  Constructors
    ///
    #region Constructors
    public ExclusiveCommand()
    {
    }

    //
    // SYNC (normal) CONSTRUCTORS
    //

    public ExclusiveCommand (Action<T> execute, Func<T, bool> canExecute)
    {
        Backing = new Command<T> (execute, canExecute);
    }

    public ExclusiveCommand (Action<T> execute)
    {
        Backing = new Command<T> (execute);
    }

    //
    // ASYNC CONSTRUCTORS
    //


    public ExclusiveCommand (Func<T, Task> execute, Func<T, bool> canExecute)
    {
        Backing = new AsyncCommand<T> (execute, canExecute);
    }

    public ExclusiveCommand (Func<T, Task> execute)
    {
        Backing = new AsyncCommand<T> (execute);
    }

    //
    //  End Constructors
    //
    #endregion Constructors
}

最佳答案

您可以像这样使用可选参数:

public AsyncCommand (Func<object, Task> execute, Func<object, bool> canExecute = null)
{
    this.execute = execute;
    this.canExecute = canExecute;
}

这将允许您删除您的 AsyncCommand (Func<object, Task> execute)构造函数。

你也可以只拥有你的 Func<object, Task>过载并丢弃 Func<Task>重载并要求客户编写 _ => stuff lambda 。但这可能会或可能不会被接受,具体取决于您的要求。

关于c# - 是否可以减少我在此代码中使用的构造函数的数量?多个类的构造函数重载和转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30601088/

相关文章:

c# - 我们可以将自定义对象从 Excel 传递到 C# ExcelDNA 吗?

c# - 如何根据 ASP.NET//C# 中的内容更改 ListView 中图像的 CSS 类

c# - 更新 DataGrid 从类中更新属性,该属性是绑定(bind)到 DataGrid 的 ObservableCollection 的项

c# - 转义和取消转义无效字符

c# - 如何在 ASP.NET Core 2.1 中获取客户端 IP 地址

c# - 如何在 ASP.NET 的 ListView 中的复选框的 CheckedChanged 事件中找到数据键?

C# .NET 4.6.1 Entity Framework - 尽管未调用 DB.SaveChanges(),DB.MyTable.Add(...) 仍然很慢

c# - 如何在 ASP.NET 中将下拉列表与字符串数组绑定(bind)?

c# - 使用批处理文件从命令行调用 C# exe

c# - 用于查找文本中所有关键字的高效算法