3

I have the following Interface Declaration:

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

The ShowDialog() is basically a method that will show a modal dialog box to the user. Where 'T' is the parent Form and M is the unique dialog to show. M of which there are multiple different types! Hence the reason to choose a generic method!

A couple of ways I think this method could be used:

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

Or

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

Based upon Fig A or B, what exactly will a sample ShowDialog() method implementation look like?

My questions stems from trying to figure how the generic parameter 'M' is instantiated inside of a ShowDialog() method implementation.

3
  • It's not really clear what your question is. You've said what it "stems from" but you haven't really asked a question... or explained what you mean even in the "stems from" question. Commented Sep 3, 2012 at 16:13
  • @IbrarMumtaz: No, specifying c#-4.0 doesn't specify which framework version you're using. You could be targeting .NET 2.0. Commented Sep 3, 2012 at 16:14
  • @IbrarMumtaz: Also C# has 32K followers vs 1.7K of C#-4.0. You'll be much more likely to get views. Commented Sep 3, 2012 at 16:15

4 Answers 4

5

At a guess:

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

However, frankly I'm not sure this utility method adds much useful, and it could just as well be non-generic (void ShowDialog(Control t, Form m)). It could perhaps be more useful if using the : new() constraint, which would also avoid the risk of using the same control instance on multiple forms (illegal). But as I say: frankly I wouldn't bother with this method until it had demonstrated some non-trivial usefulness. And if I did keep it, I'd rename the parameters to be more illuminating; none of M, m, T, t tell me what they mean.

Sign up to request clarification or add additional context in comments.

4 Comments

+1 I agree with the point about generics not making much sense here.
actually making it non generic makes sense here so ty!
@IbrarMumtaz btw, forgot to say - but FigB makes more sense here, except for the fact that it will never get disposed. You might want to add a using(m) {...} around everything.
Yeah. Unless something specific to a derived Control or Form has to be done, the assignement compatibility of derived types alone solves the problem and generics are completely superfluous.
4

You cannot use the Fig A way because typeof(Form1) is a System.Type, not a Form; the code will not compile unless there is an overload that takes a second parameter of type System.Type.

how the generic parameter 'M' is instantiated inside of a ShowDialog() method implementation?

It is not "instantiated" it is "inferred:. You provided the instance already; the compiler infers the type from the invocation.

Comments

2

You could change the generic method signature as follows:

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

and then the call:

ShowDialog<MyCoolDialog>();

would result in the mtheod creating (not inferring this time ;)) a new instance of the form and showing it in a modal way.

2 Comments

Note: if doing this, adding a using to the new form would be a good idea, otherwise the form won't be disposed. Of course, that might then mean that removing the control "t" would be a good idea too.
Thanks for this, this is pretty much the nudge in the right direction I needed. I will post up my answers tomorrow to show what the 'ShowDialog()' now looks like and how I used it. Hopefully it can educate some others ppl in a similar situation.
0

Below is an slightly updated version of the interface method:

    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();

I made some assumptions on the previous version so during my testing and refinement phase the method signature has changed. It's still more or a less a en educational exercise for me so I still wanted to know how to pull it off rather than simple chose the easy way out.

A sample implementation of the method:

    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();
            }
        }
    }

I am not entirely sure why the 'TDialogForm m' parameter is still in there as it does not seem to be used anywhere.

How to use the method:

    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);
    }

I should update the interface method but it was so much pain getting it to work I would rather leave it alone now =).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.