3

我有以下接口声明:

public interface IBasePresenter
{
    void Run();
    void ShowDialog<T, M>(T t, M m ) where T : UserControl where M : Form,      ISomeInterface<SomeType>;
}

ShowDialog() 基本上是一种向用户显示模式对话框的方法。其中“T”是父表单,M 是要显示的唯一对话框。M 其中有多种不同的类型!因此选择通用方法的原因!

我认为可以使用这种方法的几种方法:

Presenter.ShowDialog(this, typeof(Form1)); // FigA

或者

Presenter.ShowDialog(this, new Form1()); // FigB

根据图 A 或 B,样例 ShowDialog() 方法实现究竟是什么样的?

我的问题源于试图弄清楚通用参数“M”是如何在 ShowDialog() 方法实现中实例化的。

4

4 回答 4

5

猜测:

m.Controls.Add(t);
m.ShowDialog();

但是,坦率地说,我不确定这个实用方法是否有用,它也可以是非泛型的(void ShowDialog(Control t, Form m))。如果使用约束可能会更有用: new(),这也将避免在多个表单上使用相同的控件实例(非法)的风险。但正如我所说:坦率地说,在它展示出一些非平凡的有用性之前,我不会使用这种方法。如果我确实保留了它,我会重命名参数以更具启发性;M, m, T, t 都没有告诉我他们的意思。

于 2012-09-03T16:15:16.817 回答
4

你不能使用这种Fig A方式,因为typeof(Form1)是 a System.Type,而不是 a Form; 除非有采用第二个类型参数的重载,否则代码不会编译System.Type

如何在 ShowDialog() 方法实现中实例化泛型参数“M”?

它不是“实例化的”,而是“推断的:。您已经提供了实例;编译器从调用中推断出类型。

于 2012-09-03T16:16:52.817 回答
2

您可以按如下方式更改通用方法签名:

public void ShowDialog<T>() where T : Form, new() {
    using(var dialog = new T()){
        dialog.ShowDialog();
    }
}

然后调用:

ShowDialog<MyCoolDialog>();

将导致 mtheod 创建(这次不推断;))表单的新实例并以模态方式显示它。

于 2012-09-03T16:18:57.963 回答
0

以下是接口方法的略微更新版本:

    void ShowDialog<TParentForm, TDialogForm, TModel, TEntity>(TParentForm t, TDialogForm m, Action callback)
        where TParentForm : UserControl
        where TModel : class, IModel<TEntity>, new()
        where TDialogForm : Form, IEditableItem<TEntity>, new();

我对以前的版本做了一些假设,所以在我的测试和改进阶段,方法签名发生了变化。对我来说,这或多或少还是一个教育练习,所以我仍然想知道如何完成它,而不是简单地选择简单的方法。

该方法的示例实现

    public void ShowDialog<TParentForm, TDialogForm, TModel, TEntity>(TParentForm t, TDialogForm m, Action callback)
        where TParentForm : UserControl
        where TModel : class, IModel<TEntity>, new()
        where TDialogForm : Form, IEditableItem<TEntity>, new()
    {
        using (var dialogToShow = new TDialogForm())
        {
            dialogToShow.StartPosition = FormStartPosition.CenterScreen;
            dialogToShow.FormBorderStyle = FormBorderStyle.FixedSingle;
            dialogToShow.Model = new TModel();

            // 2. show the new user control/form to the user.
            var result = dialogToShow.ShowDialog(t);

            // 3. handle the dialog result returned and update the UI appropriately.
            if (result == DialogResult.OK)
            {
                // print status label.
                callback.Invoke();
            }
        }
    }

我不完全确定为什么“TDialogForm m”参数仍然存在,因为它似乎没有在任何地方使用。

使用方法

    private void BtnAddNewServiceClick(object sender, EventArgs e)
    {            
        Presenter.ShowDialog<ServerRolesControl, AddNewServiceForm, ServiceModel, Role>(this, new AddNewServiceForm(), SetAddedRolesLabel);
    }

    private void BtnViewAllServicesClick(object sender, EventArgs e)
    {
        Presenter.ShowDialog<ServerRolesControl, ViewRolesForm, ServiceModel, Role>(this, new ViewRolesForm(), SetDeletedRolesLabel);
    }

我应该更新接口方法,但是让它工作太痛苦了,我宁愿现在不管它=)。

于 2012-09-11T14:47:18.377 回答